Metadata-Version: 2.4
Name: pyvivc
Version: 2.0
Summary: numerical deconvolution and convolution methods working for inequal and incompatible timepoints between impulse and response curves for application in IVIVC level A
Home-page: https://github.com/scheckley/pyvivc
Author: Stephen Checkley
Author-email: scheckley@gmail.com
Project-URL: Bug Reports, https://github.com/scheckley/pyvivc
Classifier: Programming Language :: Python :: 3
Classifier: License :: OSI Approved :: GNU General Public License v3 (GPLv3)
Classifier: Operating System :: OS Independent
Requires-Python: >=3.9
Description-Content-Type: text/markdown
License-File: LICENSE.txt
Requires-Dist: scipy
Requires-Dist: numpy
Dynamic: author
Dynamic: author-email
Dynamic: classifier
Dynamic: description
Dynamic: description-content-type
Dynamic: home-page
Dynamic: license-file
Dynamic: project-url
Dynamic: requires-dist
Dynamic: requires-python
Dynamic: summary

# Pyvivc

## Version 2.0
Stephen Checkley, October 2021.

---

## Description
A Python 3 port of the Rivivc R package for IVIVC linear level A by Aleksander Mendyk and Sebastian Polak. The package contains a numerical deconvolution method working for inequal and incompatible timepoints between impulse and response curves. A numerical convolution method is also included.

This version faithfully reproduces the algorithm of Rivivc 0.9 and has **no pandas dependency** — curves are passed as plain numpy arrays with two columns: column 0 = time, column 1 = concentration.

---

## Installation

Clone the repository and install with pip:

```
pip install .
```

or install with pip from the PyPi repository:

```
pip install pyvivc
```

## Pyvivc example

    from pyvivc import *
    import numpy as np
    import matplotlib.pyplot as plt
    import matplotlib
    matplotlib.use('TkAgg')


    def load_curve(path):
        # skip the "time,C" header; return an (n, 2) float array
        return np.genfromtxt(path, delimiter=',', skip_header=1)


    impulse = load_curve('data/impulse.csv')
    response = load_curve('data/resp.csv')
    inp = load_curve('data/input.csv')

    out = pyivivc(inp, impulse, response,
                  explicit_interpolation=10, implicit_interpolation=5)

    regression = out[0]   # scipy linregress result
    numeric = out[1]      # numpy array: col 0 = time, col 1 = par

    x = inp[:, 1]         # input dissolution (fraction)
    y = numeric[:, 1]     # deconvolved input

    rsquare_text = 'R squared = ' + str(round(regression.rvalue, 2))

    plt.subplot(1, 2, 1)
    plt.plot(x, y, 'o', label='data')
    plt.plot(y, regression.intercept + regression.slope * y, 'r')
    plt.annotate(rsquare_text, (0, 0.8), horizontalalignment='left',
                 verticalalignment='top', fontsize=8)
    plt.xlabel('input data (#)')
    plt.ylabel('deconvolved input (#)')
    plt.legend()

    plt.subplot(1, 2, 2)
    plt.plot(numeric[:, 0], y, 'r', label='deconvolution')
    plt.plot(inp[:, 0], inp[:, 1], 'o', label='data')
    plt.xlabel('Time')
    plt.ylabel('discovered input (%)')
    plt.legend()

    plt.show()


## API

All curves are numpy arrays of shape `(n, 2)`: column 0 = time, column 1 = concentration.

- `NumConv(impulse, input, conv_timescale=None, explicit_interpolation=1000)`
  returns a dict with keys `par` and `par_explicit` (each an `(n, 2)` numpy array).
- `NumDeconv(impulse, response, dose_iv=None, dose_po=None, deconv_timescale=None, explicit_interpolation=20, implicit_interpolation=10, maxit_optim=200)`
  returns a dict with keys `par`, `par_explicit`, and `par_implicit`.
- `pyivivc(known_dat, impulse, second_profile, ...)`
  returns `[scipy_linregress_result, numeric_array]`.

![The output should look like this](https://github.com/scheckley/pyvivc/blob/master/example_plot.png?raw=true)
---
