1

I keep getting "Cannot operate with Quantity and Quantity of different registries." errors and I cannot figure out why. In the following code snippet, Pint creates one registry used to populate the constants/fluid dictionaries. When I create a DataFrame from numerical data, Pint uses a different registry...and I have NO idea why.

Sorry it's a somewhat longer MWE. The loop/equation at the bottom is what throws the error, but I added some print statements to check the unit registries and they are indeed different...help?

EDIT: If I restart the kernel Pint only uses one registry. But on any subsequent run, even if I clear the variables, I get two different registries. I'm not sure if that's helpful to anyone, but it's more information. I would want the program to only use one registry even if I run it multiple times in the same kernel....

from __future__ import print_function, absolute_import, division
import pandas as pd
import pint # Units
import pint_pandas as ppi

# Unit Registry
ureg = pint.UnitRegistry(auto_reduce_dimensions=False)
pint.set_application_registry(ureg)
ppi.PintType.ureg = ureg
ppi.PintType.ureg.default_format = "~P"

# Constants and Parameters
#Acceleration Due to Gravity
g = 1.0 * ureg.g_0
g.ito(ureg.foot / ureg.second**2 ) # ft/s2

print('Constants Dictionary Unit Registries')
print('g: ', id(g._REGISTRY))

# Constants Dict
const_dict = {}
const_dict['g'] = g
const_dict['SL_LB'] = 1.0*ureg.slug/(1.0*ureg.slug).to(ureg.pound) # slug/lb
const_dict['rho'] = 68.48 * ureg.pound / ureg.foot**3  #lbMass/ft^3
const_dict['eta'] = 0.6644 * ureg.centipoise

# Check registry of constants dictionary
cdg = const_dict['g']
print('cdg: ', id(cdg._REGISTRY))

# Fluid Dict
fluid_dict = {}
fluid_dict['Dens_SL'] = const_dict['rho'] * const_dict['SL_LB'] # slugs/ft3
fluid_dict['DynVisc_LBFT2'] = const_dict['eta'].to(ureg.force_pound * ureg.second / ureg.foot**2) #lbF-s/ft2

# Check registry of fluid dictionary
fdex = fluid_dict['Dens_SL']
print('Fluid Dictionary Unit Registries')
print('fdex: ', id(fdex._REGISTRY))

# Small segment of the input data
Dij = [4.0]*4
Lij = [2000.0]*4
data = {'Dij': Dij, 'Lij': Lij}
arc = pd.DataFrame(data=data)

# Put Data into DataFrame
df = pd.DataFrame({
        "Dij": ppi.PintArray(arc['Dij'], dtype=ureg.inch),
        "Lij": ppi.PintArray(arc['Lij'], dtype=ureg.foot)
    }, index=arc.index)

print('DataFrame Unit Registries')
ID = df.at[0,'Dij']
print('ID: ', id(ID._REGISTRY))

v = list(range(1,3))
vels = ppi.PintArray(v, dtype=ureg.foot/ureg.second)

# Check registry of Pint Array content
vt=vels[0]
print('V: ', id(vt._REGISTRY))

vvels = [vels]*len(arc)
vv = list(zip(arc.index.values, vvels))
vd = dict(vv)
pwdf = pd.DataFrame(vd, index=v)
pwdf2 = pwdf.T

# Breaks here....
#for y in vels:
#    ReNumb = y * ID * fluid_dict['Dens_SL'] / fluid_dict['DynVisc_LBFT2']
#    ReNumb.ito_reduced_units()
#    print(ReNumb)

Which creates the following output:

Constants Dictionary Unit Registries
g:  140211922283536
cdg:  140211922283536
Fluid Dictionary Unit Registries
fdex:  140211922283536
DataFrame Unit Registries
ID:  140211870589664
V:  140211870589664

Somewhat obviously, the actual registry NUMBERS change sometimes between code execution, but, bottom line, the first three are always different from the last two...

Jennifer
  • 31
  • 5

1 Answers1

1

Apparently if I use get_application_registry instead of set_application_registry, it works fine. I don't really understand why because the example on the Pint website is:

from pint import UnitRegistry, set_application_registry
ureg = UnitRegistry()
set_application_registry(ureg)

But yeah, "set" doesn't work for me...I need to use "get".

ureg = pint.get_application_registry()
Jennifer
  • 31
  • 5