Library to make laboratory calculations easy
Project description
Pysics
Pysics is a Python module designed to perform calculations typically done in physics laboratories. It is based on the use of the "Measure" class, which allows storing measures with errors and performing standard approximation (first significant digit of the error, two if it is a 1).
Table of Contents
Installation
The library is available in pip so you can install it with:
pip install pysics
Basic Operations
The fundamental part of the module is the Measure class. Initializing an object can be done in several ways.
# If it is a measure without error because it is negligible or for some other reason, it can be done simply by passing the value
m = Measure(9.81)
# If we have an error, it will be passed as the second argument, e.g., (7.831 ± 0.0138).
a = Measure(7.831, 0.0138)
If we execute the previous line, we will see that the result of a
is 7.831 ± 0.014.
This is because by default, Measure performs the approximation when initializing the object.
To avoid this, you can pass the argument approximate=False
b = Measure(7.831, 0.0138, approximate=False)
If we want to perform the approximation later, it can be done with .approx()
b.approx()
# approx also returns a pointer to the object, which allows things like
b = b.approx()
# now a==b
# or
c = (a+b).approx()
# which would be equivalent to
c = a+b
c.approx()
Measures can also be a list of several values, e.g., c = 1.1 ± 0.1, 2.2 ± 0.1, 3.3 ± 0.1
# Since all values have the same error, it is enough to write it once
c = Measure([1.1, 2.2, 3.3], 0.1, approximate=False)
d = 1.1 ± 0.1, 2.2 ± 0.2, 3.3 ± 0.3 In this case, there are different errors, so two lists are passed: the first contains the values, and the second contains the errors such that the index of each list is a value and its corresponding error. If the lists do not have the same length, an error will be thrown.
d = Measure([1.1, 2.2, 3.3], [0.1, 0.2, 0.3])
For this kind of Measures, the class method "from_pairs" is provided, which allows passing a list of values in tuples. The following code is equivalent to the previous one.
d = Measure.from_pairs([1.1, 0.1], [2.2, 0.2], [3.3, 0.3], approximate=True)
Measure objects can be added, subtracted, multiplied, etc., by other Measures and by scalars, always returning other Measures. Additionally, approximations will not be performed when making a calculation; this is to allow concatenating several operations without losing precision. When performing these calculations, errors are recalculated. For ALL cases except & and ||, Measures are considered independent, so the error is the sum in quadrature. Operations between Measures are defined element by element, i.e., the first is added to the first, the second to the second, etc. Operations with scalars are defined as the operation of the scalar over the entire measure, e.g., c+1 will result in Measure([1.1 + 1, 2.2 + 1, 3.3 + 1], [0.1], approximate=False). If there is a measure with a single value, e.g., Measure(1, 0.1), it will be considered as a scalar taking into account the error. If two Measures with different numbers of elements are added, and neither has a single element, e.g., Measure([1, 2]) + Measure([1, 2, 3]), an error will be thrown.
e = (a+b).approx() # 15.662 ± 0.02
f = (c*d).approx() # 1.21 ± 0.16, 4.8 ± 0.5, 10.9 ± 1.0
If two Measures are dependent and want to be added or subtracted, the operators & and | should be used.
# To add dependent Measures, use the & operator
h = (a&b).approx() # 15.66 ± 0.03
# To subtract dependent Measures, use the | operator
i = (a|b).approx() # 0.0 ± 0.03 equivalent to (a&(-b))
To make copies of a measure, you can use the copy method. In the following example, a copy with the approximations of c is made without modifying c.
j = c.copy().approx()
# If instead of the above we used the following, we would modify c, and it is possible that certain changes applied to j would affect c
j = c.approx()
To retrieve the values of the Measures or errors in a list, you can use the properties measure
and error
.
print(d.value) # [1.1, 2.2, 3.3]
print(d.error) # [0.1, 0.2, 0.3]
measure, error = d.unpack()
To calculate the mean, standard deviation, and standard error of a measure, you can use the methods of the same name.
mean = d.mean()
standard_deviation = d.standard_deviation()
standard_error = d.standard_error() # Standard deviation of the mean
mean, standard_error = d.estimation()
Units
The Measure
object also supports operations with units. To create a Measure
with units, you can simply multiply by the unit:
a = Measure(2, 0.1) * kg
print(a) # 2 ± 0.1 kg
This will create a
as a measure with kg
as its unit. The most common units are predefined in units for your convenience. However, you can also create your own unit using the Unit
class constructor:
year = Unit(s, scale=365.25*24*3600, symbol="year")
To define a custom unit:
- Provide its equivalent in the International System of Units (SI). This can be a combination of existing units.
- Specify the
scale
factor to convert your unit to the SI unit. - Set a
symbol
for concise representation of the unit.
The scale
is the factor you multiply your unit by to convert it to the SI unit. The symbol
is used for formatting when printing the value with its unit.
Once created, you can use your custom unit just like the predefined ones.
Plot
Pysics also provides a powerful plotting API that integrates seamlessly with the Measure
class. It offers various types of plots and data fitting capabilities.
Basic Plotting
The plotting module supports different types of plots, including scatter, line and polar plots. Here's an example using them:
from pysics.plot import scatter, plot, polar_plot, show, legend
from pysics.constants import pi
import numpy as np
x = Measure([1, 2, 3, 4, 5], 0.1)
y = Measure([2, 4, 5, 4, 5], 0.2)
# Create a scatter plot with error bars
scatter(x, y, xerr=True, yerr=True, label='Data with Errors')
# The xerr and yerr parameters set to True tell the function to use the errors from the Measure objects. You can also pass a list of errors to them and it will use that list as errors.
# Create a line plot using the same data
plot(x, y, label='Data Line')
# Create a polar plot
theta = np.linspace(0, 2*pi, 100)
r = np.cos(4*theta)
polar_plot(theta, r, label='Polar Data')
# Displays the labels
legend()
# Display the plots
show()
This example demonstrates how to create diferent plots with error bars using Measure objects. The scatter
function automatically uses the error values from the Measure objects when xerr
and yerr
are set to True. There is also a polar_scatter
function.
Customizing Plots
Pysics allows for extensive customization of plots, including the use of LaTeX for rendering labels:
from pysics.plot import scatter, xlabel, ylabel, title, use_latex, show
use_latex() # Enable LaTeX rendering
x = [1,2,3,4]
y = [1,2,3,4]
scatter(x, y)
# Set axis labels and title using LaTeX syntax
xlabel(r'$x$ axis')
ylabel(r'$y$ axis')
title(r'Plot with $\LaTeX$ labels')
show()
The use_latex()
function enables LaTeX rendering for all text elements in the plot. The r
prefix before the strings denotes raw strings, which is useful when writing LaTeX code to avoid issues with backslashes.
Furthermore, since Pysics uses Matplotlib underneath, you can use Matplotlib functions to further customize your plots.
Saving Plots
Saving plots to various file formats is straightforward:
from pysics.plot import scatter, save
scatter(x, y)
save('my_plot', format='png')
This code creates a scatter plot and saves it as 'my_plot.png' in the current directory. The save
function supports various formats including 'png', 'pdf', 'svg', and more.
Fit
The Fit module in Pysics provides functions for fitting data to various models using measures. Here's an example of a linear fit:
from pysics.fit import least_squares
from pysics.plot import scatter, line
x = Measure([1, 2, 3, 4, 5], 0.3)
y = Measure([2.1, 3.9, 6.2, 7.8, 9.9], 0.1)
# Perform a linear fit
fit_result = least_squares(x, y)
# Plot the original data
scatter(x, y)
# Plot the fit line
line(x, fit_result)
show()
In this example, least_squares
performs a linear fit on the data. The resulting fit_result
contains the parameters of the fit (slope and intercept) as Measure objects, including the errors of the fit. The line
function then uses these parameters to plot the fit line.
Here's another example of fitting data, this time we use a custom function:
from pysics.fit import curve as curve_fit
from pysics.plot import curve as curve_plot, show
def quadratic(x, a, b, c):
return a * x**2 + b * x + c
x = [0, 1, 2, 3, 4, 5]
y = [1, 2.1, 5.2, 10.3, 17.4, 26.5]
fit_params = curve_fit(quadratic, x, y)
# Plot the fit curve
curve_plot(quadratic, x, fit_params)
show()
In this example:
- We define a quadratic function
quadratic(x, a, b, c)
that represents our model. - We provide x and y data points.
- The
curve_fit
function fits the data to the quadratic model. fit_params
contains the best-fit values for a, b, and c as Measure objects, including their uncertainties.curve_plot
function plots the obtained curve.
This powerful fitting capability allows you to fit your data to any custom function, making it versatile for various scientific applications.
Func
The func
module provides a comprehensive set of mathematical and physics-related functions that work seamlessly with the Measure
class. The functions available are:
- Trigonometric functions: sin, cos, tan, and their inverses (asin, acos, atan)
- Angular conversions: rad (degrees to radians) and grad (radians to degrees)
- Logarithmic and exponential functions: ln, exp
- Other mathematical operations: sqrt, atan2 (polar coordinate angle)
- Utility functions: delta (difference between consecutive values)
All these functions are designed to work with Measure
objects, handling both scalar and array inputs.
Examples of usage:
- Trigonometric functions:
from pysics import Measure, units, func
angle = Measure(45, 1, units=units.deg)
sin_value = func.sin(func.rad(angle))
print(f"sin(45°) = {sin_value}")
- Inverse trigonometric functions:
x = Measure(0.5, 0.01)
angle = func.asin(x)
print(f"arcsin(0.5) = {angle}")
- Logarithmic and exponential functions:
value = Measure(10, 0.1)
log_value = func.ln(value)
exp_value = func.exp(Measure(1, 0.01))
print(f"ln(10) = {log_value}")
print(f"e^1 = {exp_value}")
- Square root:
number = Measure(16, 0.5)
root = func.sqrt(number)
print(f"sqrt(16) = {root}")
- Polar coordinate angle:
x = Measure(3, 0.1)
y = Measure(4, 0.1)
angle = func.atan2(y, x)
print(f"atan2(4, 3) = {angle}")
- Delta function (for array inputs):
values = Measure([1, 3, 6, 10], [0.1, 0.1, 0.2, 0.2])
differences = func.delta(values)
print(f"Differences: {differences}")
These functions automatically handle error propagation, making it easy to perform complex calculations while keeping track of uncertainties. They also include warnings for potentially incorrect usage, such as passing non-angular values to trigonometric functions.
Read
The reader
module in Pysics provides functions for loading data from files and saving data in LaTeX format.
To load data from a file:
from pysics.reader import load
data = load("input.txt", separator=",", headers=1)
The load
function parameters are:
file
: Path to the input file.separator
: Character used to separate values (default: '\t').line
: Character used to separate rows (default: '\n').decimal
: Character used as decimal separator (default: ',').headers
: Number of header rows to skip (default: 0).by_columns
: If True, organizes data by columns; if False, by rows (default: True).
To save data in LaTeX format:
from pysics.reader import save_latex
save_latex("output.tex", data, separator="&", style=Measure.Style.scientific)
The save_latex
function parameters are:
file
: Path to the output file.data
: List of data to be saved.separator
: Character used to separate values (default: '\t').line
: Character used to separate rows (default: '\n').by_columns
: If True, organizes data by columns; if False, by rows (default: True).style
: Style for formatting Measure objects (default: Measure.Style.latex_table).
This function converts the input data to strings, ensures consistent row lengths, and writes the formatted data to the specified file.
Tables
The tables
module in Pysics provides utilities for creating and formatting tables in various output formats.
To create a formatted table as a list of lists:
from pysics.tables import create_table_list
data = [[1, 2, 3], [4, 5, 6]]
header = ['A', 'B', 'C']
formatted_table = create_table_list(data, header=header, style=Measure.Style.table)
To create a string representation of a table for terminal display:
from pysics.tables import terminal
data = [[1, 2, 3], [4, 5, 6]]
header = ['A', 'B', 'C']
print(terminal(data, header=header))
To create a LaTeX representation of a table:
from pysics.tables import latex
data = [[1, 2, 3], [4, 5, 6]]
header = ['A', 'B', 'C']
latex_table = latex(data, header=header, caption="My Table", label="tab:example")
print(latex_table)
To create a Typst representation of a table:
from pysics.tables import typst
data = [[1, 2, 3], [4, 5, 6]]
header = ['A', 'B', 'C']
typst_table = typst(data, header=header)
print(typst_table)
These functions provide flexible table formatting options for various output formats, making it easy to present data in the desired style for different applications.
Acknowledgements
Special thanks to Jonathan Dönszelmann for the pypi project name
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
File details
Details for the file pysics-0.1.0.tar.gz
.
File metadata
- Download URL: pysics-0.1.0.tar.gz
- Upload date:
- Size: 30.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/5.1.1 CPython/3.12.4
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | be8b4a6a39b581eccecaf51b06763e9c32269e9951d39a420647c224936c8bc2 |
|
MD5 | f0df10f73f3373c130860b0708b79763 |
|
BLAKE2b-256 | 8725e13317ce4cd815d7079ebd8148d4ec9b89d19f8504294873e1e9d56b60d8 |
File details
Details for the file pysics-0.1.0-py3-none-any.whl
.
File metadata
- Download URL: pysics-0.1.0-py3-none-any.whl
- Upload date:
- Size: 27.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/5.1.1 CPython/3.12.4
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | ae7d12e30ab8ba75882873d1fdd78cbf59b86310fb9a3212c639ec1fe39efe8c |
|
MD5 | 9123c4244dc27ca9cbda7a498947ea38 |
|
BLAKE2b-256 | 9ab5745a0271562d4515b5da2fa0ffa05383fd0a86446cdc333b714c0abec111 |