44
55from hashlib import md5
66from math import isnan
7+ from bson .dbref import DBRef
78from datetime import datetime
89from flask import current_app
910from atlasq import AtlasManager , AtlasQ
1819from boltons .iterutils import remap
1920from decimal import Decimal
2021from pint import UnitRegistry
21- from pint .unit import UnitDefinition
22- from pint .converters import ScaleConverter
2322from pint .errors import DimensionalityError
2423from uncertainties import ufloat_fromstr
2524from pymatgen .core import Composition , Element
3534 lambda s : s .replace ("%" , " percent " ),
3635 ],
3736)
38- ureg .default_format = "~,P"
39-
40- ureg .define (UnitDefinition ("percent" , "%" , (), ScaleConverter (0.01 )))
41- ureg .define (UnitDefinition ("permille" , "%%" , (), ScaleConverter (0.001 )))
42- ureg .define (UnitDefinition ("ppm" , "ppm" , (), ScaleConverter (1e-6 )))
43- ureg .define (UnitDefinition ("ppb" , "ppb" , (), ScaleConverter (1e-9 )))
37+ ureg .formatter .default_format = "~,P"
38+
39+ if "percent" not in ureg :
40+ # percent is native in pint >= 0.21
41+ ureg .define ("percent = 0.01 = %" )
42+ if "permille" not in ureg :
43+ # permille is native in pint >= 0.24.2
44+ ureg .define ("permille = 0.001 = ‰ = %%" )
45+ if "ppm" not in ureg :
46+ # ppm is native in pint >= 0.21
47+ ureg .define ("ppm = 1e-6" )
48+ ureg .define ("ppb = 1e-9" )
4449ureg .define ("atom = 1" )
4550ureg .define ("bohr_magneton = e * hbar / (2 * m_e) = µᵇ = µ_B = mu_B" )
4651ureg .define ("electron_mass = 9.1093837015e-31 kg = mₑ = m_e" )
@@ -68,12 +73,12 @@ def format_cell(cell):
6873 return cell
6974
7075 q = get_quantity (cell )
71- if not q or isnan (q .nominal_value ):
76+ if not q or isnan (q .magnitude . nominal_value ):
7277 return cell
7378
7479 q = truncate_digits (q )
7580 try :
76- return str (q .nominal_value ) if isnan (q .std_dev ) else str (q )
81+ return str (q .magnitude . nominal_value ) if isnan (q . magnitude .std_dev ) else str (q )
7782 except Exception :
7883 return cell
7984
@@ -102,10 +107,10 @@ def get_quantity(s):
102107
103108
104109def truncate_digits (q ):
105- if isnan (q .nominal_value ):
110+ if isnan (q .magnitude . nominal_value ):
106111 return q
107112
108- v = Decimal (str (q .nominal_value ))
113+ v = Decimal (str (q .magnitude . nominal_value ))
109114 vt = v .as_tuple ()
110115
111116 if vt .exponent >= 0 :
@@ -114,8 +119,8 @@ def truncate_digits(q):
114119 dgts = len (vt .digits )
115120 dgts = max_dgts if dgts > max_dgts else dgts
116121 s = f"{ v :.{dgts }g} "
117- if not isnan (q .std_dev ):
118- s += f"+/-{ q .std_dev :.{dgts }g} "
122+ if not isnan (q .magnitude . std_dev ):
123+ s += f"+/-{ q .magnitude . std_dev :.{dgts }g} "
119124
120125 if q .units :
121126 s += f" { q .units } "
@@ -260,7 +265,7 @@ def make_quantities(path, key, value):
260265 return key , value
261266
262267 # silently ignore "nan"
263- if isnan (q .nominal_value ):
268+ if isnan (q .magnitude . nominal_value ):
264269 return False
265270
266271 # ensure that the same units are used across contributions
@@ -288,11 +293,11 @@ def make_quantities(path, key, value):
288293 q = truncate_digits (q )
289294
290295 # return new value dict
291- display = str (q .value ) if isnan (q .std_dev ) else str (q )
296+ display = str (q .value ) if isnan (q .magnitude . std_dev ) else str (q )
292297 value = {
293298 "display" : display ,
294- "value" : q .nominal_value ,
295- "error" : q .std_dev ,
299+ "value" : q .magnitude . nominal_value ,
300+ "error" : q .magnitude . std_dev ,
296301 "unit" : str (q .units ),
297302 }
298303 return key , value
@@ -307,10 +312,11 @@ def pre_delete(cls, sender, document, **kwargs):
307312 document .reload (* args )
308313
309314 for component in COMPONENTS .keys ():
310- # check if other contributions exist before deletion!
311- for idx , obj in enumerate (getattr (document , component )):
315+ # check if other contributions exist before deletion
316+ # and make sure component still exists (getattr converts ref to object)
317+ for obj in getattr (document , component ):
312318 q = {component : obj .id }
313- if sender .objects (** q ).count () < 2 :
319+ if sender .objects (** q ).count () < 2 and not isinstance ( obj , DBRef ) :
314320 obj .delete ()
315321
316322
0 commit comments