fpex0 API documentation

# fpex0

# FPEX0 Python

Authors: Michael Strik and Andreas Sommer at the Interdisciplinary Center for Scientific Computing (IWR), University of Heidelberg.

This package gives a Python implementation of the FPEX0 method
for data-driven de-smearing of DSC signals presented in the paper

Sommer, Andreas; Hohenauer, Wolfgang; Barz, Tilman:
Data-driven de-smearing of DSC signals.
J Therm Anal Calorim (2022).
https://doi.org/10.1007/s10973-022-11258-y

A Matlab version of FPEX0 is available at https://github.com/andreassommer/fpex0

## Installing the package

The fpex0 package can be installed via pip:

    pip install fpex0

## Running an example

The software comes with an example implemented in `fpex0.example.exampleFit()`, that can be run by:

    import fpex0
    fpex0.example.exampleFit()

It will import measurements, build a setup and execute the algorithm.
After about 20 steps it should give a solution near by:

>       p = [-0.9555,  0.03284, 0.2862, 3.4171, 2.5246, 43.0456, 131.8116, 3.5925, 0.1893]

## Extrapolating your own data

The heart of the package are the function `fpex0.fit()` and the class `fpex0.Setup`. `Setup` holds your measurements and all problem-related configurations, e.g. your initial distribution and its inital parameters. Then `fit()` uses your setup to fit the Fokker-Planck evolution to the measurements as an optimization problem.
Reading the source code of `exampleFit()` and `exampleSetup()` should give a good understanding how the software can be used. We also recommend reading about sympy symbolic functions if not familiar.

## Data processing

The functions described above assume baseline corrected data, so raw measurements must be processed. The submodules `CP`, `baseline` can do that for you.
Processing consists of two parts:

- calculating heat capacities,
- detecting a baseline and subtracting it.

Both of it is done by `addCP()`, it will also do some previous data preparation.
As there is no code example, we will explain its usage:

1. Create a DSC_Data object and load measurements

    dsc_data = DSC_Data()
    dsc_data.T = T
    dsc_data.dsc = dsc
    dsc_data.rate = rate

1. Process

    dsc_data = addCP(dsc_data)

1. Create fpex0 setup and import your data

    FPEX0setup = Setup(gridObj, parametersObj, integrationObj, FPdriftFcn, FPdiffusionFcn, IniDistFcn)
    FPEX0setup.importDSCobj(dsc_data)

Now you can modify the setup and finally extrapolate your data via

    fit = fpex0.fit(FPEX0setup)

Note that both `addCP()` and `importDSCobj()` can also take lists of `DSC_Data` objects:

    dsc_data = addCP([dsc_data1, dsc_data2, dsc_data3])
    # now dsc_data holds a list
    FPEX0setup.importDSCobj(dsc_data)

If you want to skip one of the steps, check for

- `CP_DIN11357()` and `CP_sapphire_DIN11357()` (heat capacities),
- `subtractBaseline()` and `getBaseline()` (baseline).

These sets of functions can execute the raw single steps.

## About the implementation

This is a Python version of Andreas Sommer's matlab implementation, which can be found at https://github.com/andreassommer/fpex0.

The Fokker-Planck equation is solved as an ODE via method of lines, using scipy's solve_ivp with BDF method as a default. This is basically a python version of matlab ode15s.
The initial distribution, drift and diffusion are then fitted to the measurement data via an optimizer, by default scipy's least_squares (which is also currently the only option).
Other optimizers and integrators can be implemented by the user, if compatible to the interplay of `fpex0.fit()`, `residual()` and `simulate()`. However, the software is designed around the method of lines, so using another method to solve Fokker-Planck will require significant adjustments.

View Source

     1"""
     2.. include:: ../README.md
     3"""
     4
     5from .fpex0 import *
     6from .setup import *
     7from .InitialDistribution import *
     8from .fokker_planck import FokkerPlanck
     9from .linreg import *
    10from .CP import *
    11from .baseline import *
    12
    13from . import example