Coder Social home page Coder Social logo

nrc-cnrc / metrolopy Goto Github PK

View Code? Open in Web Editor NEW
33.0 33.0 6.0 10.03 MB

Tools for uncertainty propagation and measurement unit conversion — Outils pour la propagation des incertitudes et la conversion d'unités de mesure

Home Page: https://nrc-cnrc.github.io/MetroloPy

License: GNU General Public License v3.0

Python 100.00%
curve-fitting error-propagation ipython jupyter metrology monte-carlo-simulation python3 uncertainties uncertainty uncertainty-analysis uncertainty-propagation uncertainty-visualisation unit-conversion unit-converter

metrolopy's People

Contributors

ftessier avatar hvparks avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

metrolopy's Issues

Missing Feature

A function normalizing the gummy to the corresponding SI unit would be nice, i.e., gummy.x in SI and gummy.U in SI

gummy.create() with covariance matrix mutates input matrix

Hi,

I noticed that gummy.create() mutates its input covariance matrix.
This leads to unexpected behavior:

from metrolopy import gummy
import numpy as np

val = [1., 2.]
cov = np.array([[0.3, 0.1], [0.1, 0.2]])

print("cov before gummy creation:\n", cov)
print()

a, b = gummy.create(val, covariance_matrix=cov)

print("cov after gummy creation:\n", cov)
print()
print("a + b after first gummy creation ", a + b)

a, b = gummy.create(val, covariance_matrix=cov)

print("a + b after second gummy creation ", a + b)
cov before gummy creation:
 [[0.3 0.1]
 [0.1 0.2]]

cov after gummy creation:
 [[1.         0.40824829]
 [0.40824829 1.        ]]

a + b after first gummy creation  3.00(84)
a + b after second gummy creation  3.0(17)

I think this line is the problem:

matrix[i][j] /= gummys[i]._u*gummys[j]._u

Is the mutation necessary?
A workaround is to pass a deepcopy of the covariance matrix.

Lack of derivative causes angle() to fail on jummy

Hello,

I'm new to MetroloPy, trying to handle complex numbers with uncertainty.
I've noticed that the uc.angle() function fails on jummy objects with

~\Miniconda3\envs\default\lib\site-packages\metrolopy\dfunc.py in tofloat(self)
    193         # this should return a copy of self with the x and u properties
    194         # converted to float values
--> 195         raise NotImplementedError()
    196
    197     @classmethod

NotImplementedError:

As far as I can tell this is from MetroloPy/dfunc.py

try_fconvert = True
def _call(f,*x):
    if try_fconvert:
        try:
            return f(*x)
        except:
--->        x = [a.tofloat() if isinstance(a,Dfunc) else float(a) for a in x]
            return f(*x)

    return f(*x)

since the initial return f(*x) throws a KeyError stemming from MetroloPy/dfunc.py:

    def __array_ufunc__(self,ufunc,method,*args,**kwds):
        if method != '__call__':
            return None
        
        try:
--->        return _call(lambda *x: self._apply(ufunc,ddict[ufunc],*x), *args)
        except KeyError:
            try:
                return _call(fdict[ufunc],*args)
            except KeyError:
                return None

since ddict[np.angle] is not defined.

Calculation of combined uncertainties

Hi,

the docs don't explicitly mention this, but from looking into the source code I take it that nonlinear dependencies are implemented by linear approximation, is that correct?

thousand_spaces

As far as I know standard conform spacing is:
4.899 7 kΩ ± 1.1 Ω
4.899 68 kΩ ± 0.1 Ω
4.899 681 kΩ ± 0.01 Ω

Currently it is in the first case like this:
4.8997 kΩ ± 1.1 Ω

so the first should be: "nr < 4 and nl < 4: " and "if nr >= 4: " and " if nl >= 4:".

Modul is ummy.py

elif self.thousand_spaces:

if nr < 4 and nl < 4:
    return s + ellipses

s = list(s)
if nr >= 4:
    for i in range(int(nr/3)):
        s.insert(d + i + (i+1)*3 + 1, sp)
if nl >= 4:
    for i in range(int(nl/3)):
        s.insert(d - (i+1)*3, sp)

I love your great work with MetrolPy!
I'm sorry, for my bad contribution quality - I'm a rooky in this issue. But I'll soon learn how to to proper issues, push, pulls and what ever exist to contribute good way.

gummy.ufrom() only works for single characters

According to the docs the utype property of a gummy should accept an arbitrary string, but this only works for single characters, e.G. A/B (which are obvious choices for a utype).
I tried grouping uncertainties according to the source (DUT, REF, ...) and noticed that the gummy.ufrom() method returned a value of 0. Looking at the code, it seems that only single characters are supported. Here is a minimal example:

import metrolopy as uc

x_1 = uc.gummy(10.0, 1, utype='A')
x_2 = uc.gummy(20.0, 2, utype='DUT')
y = x_1 - x_2
print(y.ufrom('A'))
print(y.ufrom('DUT'))

documentation: definition of significance seems to be wrong

The definition of "significance" seems to be wrong. According to the docs:

“s” or “significance”: the sensitivity coefficient (below) multiplied by the standard uncertainty, displayed by default

The significance is in fact calculated as x.u / result.u (or v[0]/yu in budget.py)

If I am not mistaken, the correct text should therefore be:

“s” or “significance”: the sensitivity coefficient (below) multiplied by the standard uncertainty divided by the combined standard uncertainty, displayed by default

budget() omits names of uncertainties

Hey,

since 0.6.2 the names of uncertainties are omitted by the budget method.

Here's a minimal example:

import metrolopy as uc
x_1 = uc.gummy(42, 0, name='A')
x_2 = uc.gummy(42, 1, name='B')
y = x_1 - x_2
print(y.budget([x_1, x_2]))

output for 0.6.1

Component Value    u |dy/dx|     s
        B  42.0  1.0     1.0  1.00
        A    42    0     nan   nan
        y   0.0  1.0

output for 0.6.2

Component Value    u |dy/dx|     s
     x[2]  42.0  1.0     1.0  1.00
     x[1]    42    0     0.0     0
        y   0.0  1.0

Please notice the 'Component' column

multiplying a gummy with a complex number should create a jummy

Any operation (e.g. multiplication) of a gummy with a complex number raises an exception. It should rather create a jummy.

This probably require only some additional conditional checks in the ummy code to work and would lead to a more expectable behaviour.

0°C - Bug

If the value 0°C is entered it is automatically converted to - 273.15(15) °C. A Value slightly above ist giving the correct result.
Enclosed my code:

import metrolopy as uc

UUT = uc.gummy(0, 0.15, uunit="°C", unit="°C")
Out[4]: -273.15(15) °C

UUT = uc.gummy(0, 0.15, uunit="degC", unit="degC")
Out[8]: -273.15(15) °C

UUT = uc.gummy(0.1, 0.15, uunit="degC", unit="degC")
Out[10]: 0.10(15) °C

Bugs in unitparser.py

There are at least two bugs in unitparser.py:

  • Giving a unit as e.g. "V**(0.5)" will attempt to typecast "(0.5)" as float, when it should be typecasting "0.5" (line 212, 201, etc.). It seems to currently impossible to set fractional exponents.
  • isspace() is misspelled on several occasions (as ispace()).

Budget Values with Names

In the budget values are displayed with names if uunit of output variable is set to % or ppm.

image

Adding show_name = False to budget.py solved this issue for me:
image

Result:
image

Uniform Distribution Uncertainty Error

The standard uncertainty of the uniform distribution is not correct if it is calculated by upper and lower limit. I think you missed a factor 2 in the denominator.

image

Uncertainty not calculated correctly when working with integers as base in exponential functions

First of all, thank you for uploading this package, I was look for something like this for a while!

When testing the package (v0.5.4) on a convoluted model function which had a 10**(...) term I found that the uncertainty does not seem to be calculated correctly (double checking with a calculation by hand and the uncertainties package yielded significantly different results). By accident, I changed the integer 10 to a float 10.0**(...) which solved the problem!

Here is a minimal example:

>>> a = uc.gummy(1, u=0.1)
>>> 10**a

10.0 +/- 2.0

vs.

>>> a = uc.gummy(1, u=0.1)
>>> 10.0**a

10.0 +/- 2.3

UniformDist Error

Although the following expressions should be equivalent results differ. Only the latter is correct.

tmp = uc.gummy(uc.UniformDist(lower_limit=6,upper_limit=9),unit='pA')
uc.gummy.simulate([tmp],n=1e7)
tmp.hist(p=0.99)

image
image

tmp = uc.gummy(uc.UniformDist(center=7.5,half_width=1.5),unit='pA') 
uc.gummy.simulate([tmp],n=1e7)
tmp.hist(p=0.99)

image
image

budget() raises BudgetWarning for an uncertainty of 0

Hi,
While trying to validate metrolopy (v0.6.1) with example S9 from EA-4/02 M: 2013, I noticed that an BudgetWarning is raised for uncertainties with a value 0, when trying to create a budget. I don't want to post the whole code so here is a minimal example showcasing this:

import metrolopy as uc

x_1 = uc.gummy(42, 0)
x_2 = uc.gummy(42, 1)
y = x_1 - x_2
print(y.budget([x_1, x_2]))

the traceback is:

gummy.py:2070: BudgetWarning: the x variables are over determined; they cannot all be taken as independant variables
  return Budget(self,xlist,**kwds)
budget.py:443: RuntimeWarning: invalid value encountered in double_scalars
  d = [p*yu/q.u for p,q in zip(s,x)]
Component Value    u |dy/dx|     s
     x[2]  42.0  1.0     1.0  1.00
     x[1]    42    0     nan   nan
        y   0.0  1.0

This is by itself not a problem, since the calculation still seems to be correct and the warnings are easily captured. I just wonder if this is an intended behavior?

matplot lib normed depreciation warning

Newer versions of matplotlib raise a depreciation warning for the hist normed keyword argument ("use the density keyword argument instead") when gummy.hist() is executed.

Metrolopy2word

Here is a suggestion for a Microsoft Word export of budget and frequency distribution. Might be interesting for people who don't know Latex.

Result
image

SourceCode

from docx import Document
import matplotlib
from docx.enum.section import WD_ORIENT, WD_SECTION
from docx.shared import Mm
def budget2word(budget,file,output=None):    
    df = budget.df_str
    doc = Document()
    section = doc.sections[-1]
    section.page_height = Mm(297)
    section.page_width = Mm(210)
    section.left_margin = Mm(25.4)
    section.right_margin = Mm(25.4)
    section.top_margin = Mm(25.4)
    section.bottom_margin = Mm(25.4)
    section.header_distance = Mm(12.7)
    section.footer_distance = Mm(12.7)
    t = doc.add_table(df.shape[0]+1, df.shape[1])
    t.style = doc.styles['Colorful List Accent 2']
    for j in range(df.shape[-1]):
        t.cell(0,j).text = df.columns[j]
    for i in range(df.shape[0]):
        for j in range(df.shape[-1]):
            t.cell(i+1,j).text = df.values[i,j] 
    if output is not None:
        matplotlib.pyplot.clf()
        uc.gummy.simulate([output],n=5e5)
        output.hist(p=0.95, density=False)
        matplotlib.pyplot.gca().set_ylabel("frequency distribution")
        output.k = 1
        matplotlib.pyplot.savefig(file.split(".")[0]+".png")
        doc.add_picture(file.split(".")[0]+".png")
    doc.save(file)

Execution

fname = 'budgets/budget.docx'
budget2word(budget,fname,output=outputVariable)

Missing Feature: Uncertainty by Observations

I am missing a feature for automatic calculation of uncertainty by a given array of observations similliar to GUM Type A Bayes. Please find an example for student distribution assumptions below.

from scipy.stats import t
from scipy import special
import numpy as np

def u(x):
    confidence = special.erf(1/np.sqrt(2)) # single standard deviation 68 percent
    return t.ppf(1-(1-confidence)/2, len(x)-1)*x.std(ddof=1)/np.sqrt(len(x))

def mean(x):
    return np.mean(x)

Function _unit.mulr() does not exist

Hello,
I think I have found a typo...

un = self._unit.mulr(one)[0]

I have tested the two examples given and I get AttributeError '_CompositeUnit' object has no attribute 'mulr'
This could have been caught with a unit tests ;)
Loving this module, keep up the great work!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.