Skip to content

Commit

Permalink
finished building OPC class
Browse files Browse the repository at this point in the history
  • Loading branch information
dhhagan committed Jul 20, 2019
1 parent 2addeff commit e0f6ed7
Show file tree
Hide file tree
Showing 11 changed files with 951 additions and 548 deletions.
17 changes: 2 additions & 15 deletions docs/api.rst
Original file line number Diff line number Diff line change
Expand Up @@ -43,11 +43,10 @@ Models
.. autosummary::
:toctree: generated/

opcsim.OPC.calibrate
opcsim.OPC.evaluate
opcsim.OPC.histogram
opcsim.OPC.number
opcsim.OPC.surface_area
opcsim.OPC.volume
opcsim.OPC.integrate


.. _mie_theory_api:
Expand Down Expand Up @@ -77,18 +76,6 @@ Visualization
opcsim.plots.cdfplot


.. _scoring_api:

Evaluation and Scoring
----------------------

.. autosummary::
:toctree: generated/

opcsim.metrics.nv_score
opcsim.metrics.vv_score


.. _equations_api:

Equations
Expand Down
38 changes: 19 additions & 19 deletions opcsim/_version.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
import sys


def get_keywords():
def get_keywords(): #pragma: no cover
"""Get the keywords needed to look up the version information."""
# these strings will be replaced by git during git-archive.
# setup.py/versioneer.py will grep for the variable names, so they must
Expand All @@ -30,11 +30,11 @@ def get_keywords():
return keywords


class VersioneerConfig:
class VersioneerConfig: # pragma: no cover
"""Container for Versioneer configuration parameters."""


def get_config():
def get_config(): # pragma: no cover
"""Create, populate and return the VersioneerConfig() object."""
# these strings are filled in when 'setup.py versioneer' creates
# _version.py
Expand All @@ -48,15 +48,15 @@ def get_config():
return cfg


class NotThisMethod(Exception):
class NotThisMethod(Exception): # pragma: no cover
"""Exception raised if a method is not valid for the current scenario."""


LONG_VERSION_PY = {}
HANDLERS = {}


def register_vcs_handler(vcs, method): # decorator
def register_vcs_handler(vcs, method): # pragma: no cover
"""Decorator to mark a method as the handler for a particular VCS."""
def decorate(f):
"""Store f in HANDLERS[vcs][method]."""
Expand All @@ -68,7 +68,7 @@ def decorate(f):


def run_command(commands, args, cwd=None, verbose=False, hide_stderr=False,
env=None):
env=None): # pragma: no cover
"""Call the given command(s)."""
assert isinstance(commands, list)
p = None
Expand Down Expand Up @@ -104,7 +104,7 @@ def run_command(commands, args, cwd=None, verbose=False, hide_stderr=False,
return stdout, p.returncode


def versions_from_parentdir(parentdir_prefix, root, verbose):
def versions_from_parentdir(parentdir_prefix, root, verbose): # pragma: no cover
"""Try to determine the version from the parent directory name.
Source tarballs conventionally unpack into a directory that includes both
Expand All @@ -130,7 +130,7 @@ def versions_from_parentdir(parentdir_prefix, root, verbose):


@register_vcs_handler("git", "get_keywords")
def git_get_keywords(versionfile_abs):
def git_get_keywords(versionfile_abs): # pragma: no cover
"""Extract version information from the given file."""
# the code embedded in _version.py can just fetch the value of these
# keywords. When used from setup.py, we don't want to import _version.py,
Expand Down Expand Up @@ -159,7 +159,7 @@ def git_get_keywords(versionfile_abs):


@register_vcs_handler("git", "keywords")
def git_versions_from_keywords(keywords, tag_prefix, verbose):
def git_versions_from_keywords(keywords, tag_prefix, verbose): # pragma: no cover
"""Get version information from git keywords."""
if not keywords:
raise NotThisMethod("no keywords at all, weird")
Expand Down Expand Up @@ -214,7 +214,7 @@ def git_versions_from_keywords(keywords, tag_prefix, verbose):


@register_vcs_handler("git", "pieces_from_vcs")
def git_pieces_from_vcs(tag_prefix, root, verbose, run_command=run_command):
def git_pieces_from_vcs(tag_prefix, root, verbose, run_command=run_command): # pragma: no cover
"""Get version from 'git describe' in the root of the source tree.
This only gets called if the git-archive 'subst' keywords were *not*
Expand Down Expand Up @@ -305,14 +305,14 @@ def git_pieces_from_vcs(tag_prefix, root, verbose, run_command=run_command):
return pieces


def plus_or_dot(pieces):
def plus_or_dot(pieces): # pragma: no cover
"""Return a + if we don't already have one, else return a ."""
if "+" in pieces.get("closest-tag", ""):
return "."
return "+"


def render_pep440(pieces):
def render_pep440(pieces): # pragma: no cover
"""Build up version string, with post-release "local version identifier".
Our goal: TAG[+DISTANCE.gHEX[.dirty]] . Note that if you
Expand All @@ -337,7 +337,7 @@ def render_pep440(pieces):
return rendered


def render_pep440_pre(pieces):
def render_pep440_pre(pieces): # pragma: no cover
"""TAG[.post.devDISTANCE] -- No -dirty.
Exceptions:
Expand All @@ -353,7 +353,7 @@ def render_pep440_pre(pieces):
return rendered


def render_pep440_post(pieces):
def render_pep440_post(pieces): # pragma: no cover
"""TAG[.postDISTANCE[.dev0]+gHEX] .
The ".dev0" means dirty. Note that .dev0 sorts backwards
Expand All @@ -380,7 +380,7 @@ def render_pep440_post(pieces):
return rendered


def render_pep440_old(pieces):
def render_pep440_old(pieces): # pragma: no cover
"""TAG[.postDISTANCE[.dev0]] .
The ".dev0" means dirty.
Expand All @@ -402,7 +402,7 @@ def render_pep440_old(pieces):
return rendered


def render_git_describe(pieces):
def render_git_describe(pieces): # pragma: no cover
"""TAG[-DISTANCE-gHEX][-dirty].
Like 'git describe --tags --dirty --always'.
Expand All @@ -422,7 +422,7 @@ def render_git_describe(pieces):
return rendered


def render_git_describe_long(pieces):
def render_git_describe_long(pieces): # pragma: no cover
"""TAG-DISTANCE-gHEX[-dirty].
Like 'git describe --tags --dirty --always -long'.
Expand All @@ -442,7 +442,7 @@ def render_git_describe_long(pieces):
return rendered


def render(pieces, style):
def render(pieces, style): # pragma: no cover
"""Render the given version pieces into the requested style."""
if pieces["error"]:
return {"version": "unknown",
Expand Down Expand Up @@ -474,7 +474,7 @@ def render(pieces, style):
"date": pieces.get("date")}


def get_versions():
def get_versions(): # pragma: no cover
"""Get version information or return default if unable to do so."""
# I am in _version.py, which lives at ROOT/VERSIONFILE_SOURCE. If we have
# __file__, we can work backwards from there to the root. Some
Expand Down
2 changes: 1 addition & 1 deletion opcsim/distributions.py
Original file line number Diff line number Diff line change
Expand Up @@ -215,7 +215,7 @@ def add_mode(self, n, gm, gsd, label=None, kappa=0., rho=1., refr=1.5+0j):
"""
self.modes.append(
{
'label':label,
'label':label if label else "Mode {}".format(len(self.modes)),
'N':n, 'GM':gm,
'GSD':gsd,
"kappa": kappa,
Expand Down
176 changes: 88 additions & 88 deletions opcsim/metrics.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,91 +3,91 @@

import numpy as np

def nv_score(model, distribution, dmin=0.0, dmax=2.5, **kwargs):
"""Calculate and return the number-to-volume ratio.
The total number of particles is calculated by calculating the total number
of particles in each individual bin, and then summing them. The total volume
in the distribution is calculated by integrating the Volume-weighted CDF
between 0 and `dmax` microns.
Parameters
----------
model : OPC
A valid OPC model describing an OPC that can be evaluated.
distribution : AerosolDistribution
A valid AerosolDistribution instance that can be evaluated.
dmin : float
The minimum particle size to integrate the CDF under. Default is 0.0
microns.
dmax : float
The maximum particle size to integrate the CDF under. Default is 2.5
microns.
Returns
-------
N/V : float
Returns the number-to-volume ratio as a single float.
Examples
--------
Compute the number-to-volume ratio for a 2-bin OPC on the Urban distribution
>>> opc = opcsim.OPC(n_bins=2)
>>> urban = opcsim.load_distribution("Urban")
>>> n_v = opcsim.metrics.nv_score(opc, urban)
"""
# evaluate the total number of particles in each bin (then sum)
total_number = model.number(distribution, **kwargs).sum()

# evaluate the total volume in the distribution < dmax
total_volume = distribution.cdf(weight='volume', dmax=dmax)

return total_number / total_volume

def vv_score(model, distribution, dmin=0.0, dmax=2.5, **kwargs):
"""Calculate and return the volume-to-volume ratio.
The total volume of particles per the OPC is calculated by calculating the
total number of particles in each individual bin, and then multiplying each
bin by a 'volume-factor'. The sum of individual bin volumes is then used.
The total volume in the distribution is calculated by integrating the
Volume-weighted CDF between 0 and `dmax` microns.
Parameters
----------
model : OPC
A valid OPC model describing an OPC that can be evaluated.
distribution : AerosolDistribution
A valid AerosolDistribution instance that can be evaluated.
dmin : float
The minimum particle size to integrate the CDF under. Default is 0.0
microns.
dmax : float
The maximum particle size to integrate the CDF under. Default is 2.5
microns.
Returns
-------
V/V : float
Returns the volume-to-volume ratio as a single float.
Examples
--------
Compute the number-to-volume ratio for a 2-bin OPC on the Urban distribution
>>> opc = opcsim.OPC(n_bins=2)
>>> urban = opcsim.load_distribution("Urban")
>>> v_v = opcsim.metrics.vv_score(opc, urban)
"""
# evaluate the total number of particles in each bin (then sum)
measured_volume = model.volume(distribution, **kwargs).sum()

# evaluate the total volume in the distribution < dmax
total_volume = distribution.cdf(weight='volume', dmin=dmin, dmax=dmax)

return measured_volume / total_volume
# def nv_score(model, distribution, dmin=0.0, dmax=2.5, **kwargs):
# """Calculate and return the number-to-volume ratio.

# The total number of particles is calculated by calculating the total number
# of particles in each individual bin, and then summing them. The total volume
# in the distribution is calculated by integrating the Volume-weighted CDF
# between 0 and `dmax` microns.

# Parameters
# ----------
# model : OPC
# A valid OPC model describing an OPC that can be evaluated.
# distribution : AerosolDistribution
# A valid AerosolDistribution instance that can be evaluated.
# dmin : float
# The minimum particle size to integrate the CDF under. Default is 0.0
# microns.
# dmax : float
# The maximum particle size to integrate the CDF under. Default is 2.5
# microns.

# Returns
# -------
# N/V : float
# Returns the number-to-volume ratio as a single float.

# Examples
# --------

# Compute the number-to-volume ratio for a 2-bin OPC on the Urban distribution

# >>> opc = opcsim.OPC(n_bins=2)
# >>> urban = opcsim.load_distribution("Urban")
# >>> n_v = opcsim.metrics.nv_score(opc, urban)

# """
# # evaluate the total number of particles in each bin (then sum)
# total_number = model.number(distribution, **kwargs).sum()

# # evaluate the total volume in the distribution < dmax
# total_volume = distribution.cdf(weight='volume', dmax=dmax)

# return total_number / total_volume

# def vv_score(model, distribution, dmin=0.0, dmax=2.5, **kwargs):
# """Calculate and return the volume-to-volume ratio.

# The total volume of particles per the OPC is calculated by calculating the
# total number of particles in each individual bin, and then multiplying each
# bin by a 'volume-factor'. The sum of individual bin volumes is then used.
# The total volume in the distribution is calculated by integrating the
# Volume-weighted CDF between 0 and `dmax` microns.

# Parameters
# ----------
# model : OPC
# A valid OPC model describing an OPC that can be evaluated.
# distribution : AerosolDistribution
# A valid AerosolDistribution instance that can be evaluated.
# dmin : float
# The minimum particle size to integrate the CDF under. Default is 0.0
# microns.
# dmax : float
# The maximum particle size to integrate the CDF under. Default is 2.5
# microns.

# Returns
# -------
# V/V : float
# Returns the volume-to-volume ratio as a single float.

# Examples
# --------

# Compute the number-to-volume ratio for a 2-bin OPC on the Urban distribution

# >>> opc = opcsim.OPC(n_bins=2)
# >>> urban = opcsim.load_distribution("Urban")
# >>> v_v = opcsim.metrics.vv_score(opc, urban)

# """
# # evaluate the total number of particles in each bin (then sum)
# measured_volume = model.volume(distribution, **kwargs).sum()

# # evaluate the total volume in the distribution < dmax
# total_volume = distribution.cdf(weight='volume', dmin=dmin, dmax=dmax)

# return measured_volume / total_volume
Loading

0 comments on commit e0f6ed7

Please sign in to comment.