hgrecco / pint

Operate and manipulate physical quantities in Python
http://pint.readthedocs.org/
Other
2.4k stars 468 forks source link

Defining custom reference unit? #1551

Closed half-adder closed 2 years ago

half-adder commented 2 years ago

I'm trying to write parameterized protocols for a biology lab using Pint.

I'm trying to create a variable with "Cell Density" (e.g. 1.6e5 cells/mL).

How can I create the "Cell" unit? Since it's a "base" unit that doesn't come from any other unit. Is this possible?

Thank you!

hgrecco commented 2 years ago

Sure! Pint is 100% flexible. You need to link it to a dimension (which can be a new one). For example, if I define a cell as unit of a compartment dimension (not sure that this is a good name).

ureg.define("cell = [compartment]")

and take a look at: https://pint.readthedocs.io/en/stable/defining.html

Roy-Kid commented 2 years ago

Hi, I also encounter the same problem(I think). I want to define a reduced unit; for example, I want to let lj_energy = 300*boltzmann_constant*kelvin, and use this to calculate any energy quantity such as (400 * boltzmann_constant * kelvin).to('lj_energy). This is because in molecular dynamics packages(LAMMPS), we only need to define three fundamental units (mass, length, and energy) and then all the units can be reduced.

When I use ureg.define(lj_energy = 300*boltzmann_constant*kelvin), it ok. But when I create an energy e = 400*boltzmann_constant*kelvin and e.to('energy'), it is wrong.

image image

I don't know how to fix this.

what should I use to achieve this goal? ureg.define(lj_energy = 300*boltzmann_constant*kelvin) or register a new group/system(I have tried @system but it not work)?

Thanks in advance for your kind help!

hgrecco commented 2 years ago

I cannot reproduce this. There is something very wrong in your screen capture. The dimensionality of boltzmann_constant is wrong. Are you sure you have not tampered with the registry?

>>> ureg.boltzmann_constant.dimensionality
<UnitsContainer({'[length]': 2, '[mass]': 1, '[temperature]': -1, '[time]': -2})>
Roy-Kid commented 2 years ago

Thank you for your reminder! I totally reinstall the pint and fix this!! And could I create a base unit that is a compound unit (such as lj_energy = 300*boltzmann_constant*kelvin), and I can use unit.to_base_unit() to convert any unit to a dimensionless unit?

half-adder commented 2 years ago

Ah ok, I didn't realize the dimension could be a new one. Thank you!