Skip to content

Commit

Permalink
Merge pull request #9 from nluetts/left_right_iterator
Browse files Browse the repository at this point in the history
Left right iterator
  • Loading branch information
nluetts authored Jan 10, 2024
2 parents 592f496 + b11b094 commit ffcf851
Show file tree
Hide file tree
Showing 18 changed files with 781 additions and 206 deletions.
23 changes: 23 additions & 0 deletions .github/workflows/draft-pdf.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
on: [push]

jobs:
paper:
runs-on: ubuntu-latest
name: Paper Draft
steps:
- name: Checkout
uses: actions/checkout@v2
- name: Build draft PDF
uses: openjournals/openjournals-draft-action@master
with:
journal: joss
# This should be the path to the paper within your repo.
paper-path: paper/paper.md
- name: Upload
uses: actions/upload-artifact@v1
with:
name: paper
# This is the output path where Pandoc will write the compiled
# PDF. Note, this should be the same directory as the input
# paper.md
path: paper/paper.pdf
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,5 @@
Manifest.toml
docs/build
docs/Manifest.toml
test/current/
test/current/
paper/paper.pdf
12 changes: 6 additions & 6 deletions Project.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
name = "NoisySignalIntegration"
uuid = "bdbab1c0-76f6-415c-8ec7-0d0463b9bd16"
authors = ["Nils Luettschwager <[email protected]>"]
version = "0.2.3"
version = "1.0.0rc1"

[deps]
Distributions = "31c24e10-a181-5473-b8eb-7969acd0382f"
Expand All @@ -16,13 +16,13 @@ Statistics = "10745b16-79ce-11e8-11f9-7d13ad32a3b2"
StatsBase = "2913bbd2-ae8a-5f71-8c99-4fb6c76f3a91"

[compat]
julia = "1.5"
Distributions = "0.23, 0.24, 0.25"
LsqFit = "0.11, 0.12"
MonteCarloMeasurements = "0.9, 0.10"
Polynomials = "1.0, 2.0"
LsqFit = ">=0.11, <0.16"
MonteCarloMeasurements = "0.9, 1"
Polynomials = "1.0, <5.0"
RecipesBase = "1.0"
StatsBase = "0.33"
StatsBase = "0.33, <0.35"
julia = ">=1.5"

[extras]
NumericalIntegration = "e7bfaba1-d571-5449-8927-abc22e82249b"
Expand Down
117 changes: 117 additions & 0 deletions paper/paper.bib
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
@Article{karir2019,
author ="Karir, Ginny and Lüttschwager, Nils O. B. and Suhm, Martin A.",
title ="Phenylacetylene as a gas phase sliding balance for solvating alcohols",
journal ="Physical Chemistry Chemical Physics",
year ="2019",
volume ="21",
issue ="15",
pages ="7831-7840",
publisher ="The Royal Society of Chemistry",
doi ="10.1039/C9CP00435A",
url ="http://dx.doi.org/10.1039/C9CP00435A"
}

@article{goebench,
author = {Gottschalk,Hannes C. and Poblotzki,Anja and Suhm,Martin A. and Al-Mogren,Muneerah M. and Antony,Jens and Auer,Alexander A. and Baptista,Leonardo and Benoit,David M. and Bistoni,Giovanni and Bohle,Fabian and Dahmani,Rahma and Firaha,Dzmitry and Grimme,Stefan and Hansen,Andreas and Harding,Michael E. and Hochlaf,Majdi and Holzer,Christof and Jansen,Georg and Klopper,Wim and Kopp,Wassja A. and Kröger,Leif C. and Leonhard,Kai and Mouhib,Halima and Neese,Frank and Pereira,Max N. and Ulusoy,Inga S. and Wuttke,Axel and Mata,Ricardo A. },
title = {The furan microsolvation blind challenge for quantum chemical methods: First steps},
journal = {The Journal of Chemical Physics},
volume = {148},
number = {1},
pages = {014301},
year = {2018},
doi = {10.1063/1.5009011},
URL = {https://doi.org/10.1063/1.5009011},
eprint = {https://doi.org/10.1063/1.5009011}
}

@article{distributions1,
author = {Mathieu Besançon and Theodore Papamarkou and David Anthoff and Alex Arslan and Simon Byrne and Dahua Lin and John Pearson},
title = {Distributions.jl: Definition and Modeling of Probability Distributions in the JuliaStats Ecosystem},
journal = {Journal of Statistical Software},
volume = {98},
number = {16},
year = {2021},
keywords = {Julia; distributions; modeling; interface; mixture; KDE; sampling; probabilistic programming; inference},
issn = {1548-7660},
pages = {1--30},
doi = {10.18637/jss.v098.i16},
url = {https://www.jstatsoft.org/v098/i16}
}
% reference for the software itself
@misc{distributions2,
author = {Dahua Lin and
John Myles White and
Simon Byrne and
Douglas Bates and
Andreas Noack and
John Pearson and
Alex Arslan and
Kevin Squire and
David Anthoff and
Theodore Papamarkou and
Mathieu Besançon and
Jan Drugowitsch and
Moritz Schauer and
{other contributors}},
title = {{JuliaStats/Distributions.jl: a Julia package for probability distributions and associated functions}},
month = july,
year = 2019,
doi = {10.5281/zenodo.2647458},
url = {https://doi.org/10.5281/zenodo.2647458}
}

@article{mcm,
author = {Fredrik {Bagge Carlson}},
title = {MonteCarloMeasurements.jl: Nonlinear Propagation of Arbitrary Multivariate
Distributions by means of Method Overloading},
year = 2020,
eid = {arXiv:2001.07625},
pages = {arXiv:2001.07625},
eprint = {2001.07625},
primaryClass = {cs.MS},
url = {https://arxiv.org/abs/2001.07625},
}

@misc{uncertainties,
author = "Eric O. Lebigot",
title = "Uncertainties: a Python package for calculations with uncertainties",
url = "https://uncertainties-python-package.readthedocs.io",
year = ""
}

@article{metrolopy,
author = "Harold V. Parks",
title = "MetroloPy",
journal = "GitHub Repository",
url = "https://github.com/nrc-cnrc/MetroloPy/",
year = "2021"
}

@article{measurements,
author = {{Giordano}, Mos{\`e}},
title = "{Uncertainty propagation with functionally correlated quantities}",
pages = {arxiv:1610.08716},
primaryClass = "physics.data-an",
year = 2016,
url = {https://arxiv.org/abs/1610.08716},
}

@article{gawrilow,
author = "Maxim Gawrilow and Martin A. Suhm",
title = "Quantifying Conformational Isomerism in Chain Molecules by Linear {R}aman Spectroscopy: The Case of Methyl Esters",
journal = "Molecules",
year = 2021,
volume = 26,
pages = 4523,
doi = "10.3390/molecules26154523",
}

@article{zimmermann,
author = "Charlotte Zimmermann and Manuel Lange and Martin A. Suhm",
title = "Halogens in Acetophenones Direct the Hydrogen Bond Docking Preference of Phenol via Stacking Interactions",
journal = "Molecules",
year = 2021,
volume = 26,
pages = 4883,
doi = "10.3390/molecules26164883",
}
74 changes: 74 additions & 0 deletions paper/paper.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
---
title: 'NoisySignalIntegration.jl: A Julia package for uncertainty evaluation of numeric integrals'
tags:
- Julia
- chemistry
- physics
- measurement uncertainty
- noisy data
- numeric integration
authors:
- name: Nils O. B. Lüttschwager
orcid: 0000-0001-8459-1714
affiliation: 1
affiliations:
- name: Georg-August-University Göttingen, Institute of Physical Chemistry, Tammannstraße 6, DE-37077 Göttingen
index: 1
date: 8 July 2021
bibliography: paper.bib
---

# Summary

The evaluation of peak or band areas is a recurring task in scientific data
evaluation. For example, in molecular spectroscopy, absorption line or band
areas are often used to determine substance abundance.
NoisySignalIntegration.jl provides functionality to evaluate such signal
areas and associated uncertainties using a Monte-Carlo approach. Uncertainties
may include contributions from (potentially correlated) Gaussian noise,
baseline subtraction, and uncertainty in placing integration bounds. Uncertain
integration bounds can be defined in several ways to constrain the integration
based on the physical system under investigation (asymmetric signals, symmetric
signals, signals with identical width). The package thus offers a more
objective uncertainty evaluation than a statement based on experience or
laborious manual analysis [@goebench].

NoisySignalIntegration.jl includes a [detailed
documentation](https://nluetts.github.io/NoisySignalIntegration.jl/stable/) that
covers the typical workflow with several examples. The API uses custom
datatypes and convenience functions to aid the data
analysis and permits flexible customizations: Any probability distribution from
Distributions.jl [@distributions1; @distributions2] is a valid input to express uncertainty
in integration bounds, thus allowing to adapt the uncertainty analysis as
needed to ones state of knowledge. The core integration function can be swapped
if the included trapezoidal integration is deemed unsatisfactory in terms of
accuracy. The package uses MonteCarloMeasurements.jl [@mcm] to express
uncertain numbers which enables immediate uncertainty propagation.

# Statement of need

Several open source options for uncertainty propagation are available, e.g.
the Python packages uncertainties [@uncertainties] or MetroloPy [@metrolopy] or
Julia packages Measurements.jl [@measurements] and the aforementioned
MonteCarloMeasurements.jl [@mcm], but uncertainty evaluation when integrating
experimental x-y data is not fully addressed and requires significant effort
from the user. A straightforward solution to this problem is to fit a peak
function of appropriate shape and derive the uncertainty from the fit. However,
the data may not be described by a peak function and/or the noise may not be
normally distributed, preventing a simple least squares regression.
NoisySignalIntegration.jl was developed as a solution to this problem. While
the package was developed specifically for the determination of band area
uncertainties in the context of molecular spectroscopy [@karir2019; @gawrilow; @zimmermann],
it is applicable in any research area where signals (peaks, lines, bands,
etc.)^[The name usually depends on the specific area and context.] in x-y data
need to be integrated and a thorough uncertainty analysis is desired.

# Acknowledgements

The author thanks Charlotte Zimmermann, Maxim Gawrilow, and Robert Medel for
testing and discussions during the development of NoisySignalIntegration.jl.
The development has furthermore profited from the benchmarking spirit and
efforts in the DFG research training group GRK 2455/389479699 to analyse
experiments as rigorously as possible.

# References
30 changes: 15 additions & 15 deletions src/bounds.jl
Original file line number Diff line number Diff line change
Expand Up @@ -87,32 +87,32 @@ julia> ubs = UncertainBound([3., 7.], scale_shift_beta(2, 2, 1.3, 1.5), uc)
UncertainBound{Float64, 10000}(start = 6.3 ± 0.022, end = 7.7 ± 0.022)
```
"""
struct UncertainBound{T, N}
left::Particles{T, N}
right::Particles{T, N}
struct UncertainBound{T,N}
left::Particles{T,N}
right::Particles{T,N}
# quantiles for local baseline subtraction and plotting
_left_quantiles
_right_quantiles
end

function Base.show(io::IO, c::UncertainBound{T, N}) where {T, N}
function Base.show(io::IO, c::UncertainBound{T,N}) where {T,N}
print(io, "UncertainBound{$T, $N}(start = $(c.left), end = $(c.right))")
end


# Constructors

# Base constructor that injects quantiles
function UncertainBound(left::Particles{T, N}, right::Particles{T, N}) where {T, N}
function UncertainBound(left::Particles{T,N}, right::Particles{T,N}) where {T,N}
qs = BOUND_QUANTILES
lqs, rqs = [[quantile(lr, q) for q in qs] for lr in (left, right)]
return UncertainBound{T, N}(left, right, lqs, rqs)
lqs, rqs = [[pquantile(lr, q) for q in qs] for lr in (left, right)]
return UncertainBound{T,N}(left, right, lqs, rqs)
end


# Create a left/right bound
function UncertainBound(left::S, right::T, N::Int=10_000) where {S <: ContinuousUnivariateDistribution, T <: ContinuousUnivariateDistribution}
left = Particles(N, left)
function UncertainBound(left::S, right::T, N::Int=10_000) where {S<:ContinuousUnivariateDistribution,T<:ContinuousUnivariateDistribution}
left = Particles(N, left)
right = Particles(N, right)
return UncertainBound(left, right)
end
Expand All @@ -122,8 +122,8 @@ end
function UncertainBound(
pos::Vector{T},
width::ContinuousUnivariateDistribution,
uc::UncertainCurve{T, N}
) where {T, N}
uc::UncertainCurve{T,N}
) where {T,N}

M = length(pos)
left = Array{T}(undef, M, N)
Expand All @@ -141,7 +141,7 @@ function UncertainBound(
left[i, j], right[i, j] = left_right_from_peak(uc.x, cⱼ.y, pᵢ, wⱼ)
end
end

return [UncertainBound(Particles(left[i, :]), Particles(right[i, :])) for i in 1:M]
end

Expand All @@ -150,8 +150,8 @@ end
function UncertainBound(
pos::T,
width::ContinuousUnivariateDistribution,
uc::UncertainCurve{T, N}
) where {T, N}
uc::UncertainCurve{T,N}
) where {T,N}
bnd = UncertainBound([pos], width, uc)
return bnd[1]
end
Expand All @@ -177,5 +177,5 @@ Create a scaled and shifted `Beta(α, β)` distribution.
Samples fall in the interval [`a`, `b`].
"""
function scale_shift_beta(α, β, a, b)
return LocationScale(a, b - a, Beta(α, β))
return Beta(α, β) * (b - a) + a
end
Loading

0 comments on commit ffcf851

Please sign in to comment.