Unit conversion
xiki-tempula opened this issue · 9 comments
Is your feature request related to a problem? Please describe.
I wonder if BSS allows the https://pypi.org/project/quantities/ style unit conversion?
Describe the solution you'd like
Say I have a force constant, which is
fc = 10 * _Units.Energy.kcal_per_mol / _Units.Length.angstrom / _Units.Length.angstrom
I could do
fc.rescale(_Units.Energy.kJ_per_mol / _Units.Length.nanometer / _Units.Length.nanometer)
To rescale the unit.
This is already supported using our internal units engine, see e.g:
BioSimSpace/python/BioSimSpace/Process/_gromacs.py
Lines 2039 to 2041 in 1b0ade5
(This returns the value in the rescaled unit.)
General unit-based quantities are stored using default units, then converted to the appropriate engine-specific format internally.
@lohedges Thanks. I wonder if there is any plan of having a BSS level function to do the conversion? Instead of going through Sire each time.
You already can, e.g. by doing algebra directly with the BioSimSpace objects, i.e.:
from BioSimSpace import Units
fc = 10 * Units.Energy.kcal_per_mol / Units.Area.angstrom2
# Work out conversion factor.
print(fc / (Units.Energy.kj_per_mol / Units.Area.nanometer2))
4184.000
(With Sire.Units there is more flexibility in what things can be converted to. With BioSimSpace we support a limited set of unit based types, which allows us to validate things robustly when evaluating inputs, e.g. from the command-line.)
@lohedges Thanks. So BSS.Units supports Units.Area.angstrom2
?
@lohedges I see. Thanks, I was trying to find angstrom2 in Units.Length.
These are the core units that we support. (We can add more if needed.) These are all typed handy convenience functions for direct conversion between units of the same type. Internally we can also use Sire.Unit for a wider range of options. Our GeneralUnit type holds anything that falls outside of the core types, but results from some combination of the core types, e.g. the force constant that you created.
@lohedges I see. Thanks, I was trying to find angstrom2 in Units.Length.
No problem, we created convenience types for Area
and Volume
to save typing.
@lohedges Thanks for the help. I wonder if there is a way of checking for complex type?
I know that one could check if a unit is a type by isinstance(1*BioSimSpace.Units.angstrom, BioSimSpace.Types.Length)
.
I wonder how do one check for complex unit like kcal/mol/nm^2? it seems that I cannot do BioSimSpace.Types.Energy / BioSimSpace.Types.Length
.
There is an example here:
BioSimSpace/python/BioSimSpace/Protocol/_equilibration.py
Lines 464 to 468 in 1b0ade5
Essentially you check the dimensions of the general unit are what you expect. (The dimensions()
method returns a tuple containing the powers in terms of (angle, charge, length, mass, quantity, temperature, time)
.)