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.

 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