__all__=["create_map","wrap","PageCache","PropertyMap","ProgressBar","Properties",]from..legacyimportBaseas_Basefrom..importuse_new_apias_use_new_apifrom..legacy.BaseimportPropertyMap,Propertiesfrom._progressbarimportProgressBarfrom._pagecacheimportPageCache_use_new_api(is_base=True)wrap=_Base.wrapdef_fix_wrapped_property_base_type(CLASS):"""Private function that adds in all of the operators so that, as much as possible, the base type PropertyWrappers (e.g. NumberProperty, StringProperty) behave like numbers or strings, and can auto-convert to those types as needed. """def__value(v):try:v=v.value()exceptException:passtry:ifv.is_integer():returnint(v)exceptException:passreturnvdef__add__(obj,other):return__value(obj)+__value(other)CLASS.__add__=__add__CLASS.__radd__=__add__def__sub__(obj,other):return__value(obj)-__value(other)def__rsub__(obj,other):return__value(other)-__value(obj)CLASS.__sub__=__sub__CLASS.__rsub__=__rsub__def__eq__(obj,other):return__value(obj)==__value(other)CLASS.__eq__=__eq__def__ne__(obj,other):return__value(obj)!=__value(other)CLASS.__ne__=__ne__def__gt__(obj,other):return__value(obj)>__value(other)CLASS.__gt__=__gt__def__ge__(obj,other):return__value(obj)>=__value(other)CLASS.__ge__=__ge__def__lt__(obj,other):return__value(obj)<__value(other)CLASS.__lt__=__lt__def__le__(obj,other):return__value(obj)<=__value(other)CLASS.__le__=__le__def__float__(obj):returnfloat(obj.value())CLASS.__float__=__float__def__int__(obj):returnint(obj.value())CLASS.__int__=__int__def__str__(obj):returnstr(__value(obj))CLASS.__str__=__str___fix_wrapped_property_base_type(_Base.BooleanProperty)_fix_wrapped_property_base_type(_Base.NumberProperty)_fix_wrapped_property_base_type(_Base.StringProperty)ifnothasattr(PropertyMap,"__orig__set"):PropertyMap.__str__=lambdax:str(x.to_dict())PropertyMap.__repr__=PropertyMap.__str__def__propertymap_set(obj,key,value):try:obj.__orig__set(key,value)returnexceptException:passtry:obj.__orig__set(key,_Base.PropertyName(value))returnexceptException:passobj.__orig__set(key,_Base.PropertyName(wrap(value)))PropertyMap.__orig__set=PropertyMap.setPropertyMap.set=__propertymap_setdef__propertymap_get_string(obj,key:str):""" Return the string value associated with the passed 'key' This returns 'key' if there is no value associated """key=str(key)ifobj.specified(key):val=obj[key]ifval.has_value():returnval.value().as_string()else:returnval.source()else:returnkeyPropertyMap.get_string=__propertymap_get_string
[docs]defcreate_map(values,extras=None):"""Construct a PropertyMap from the passed values. A PropertyMap is a class that lets you either provide extra options to some of the C++ functions, or to map the default keys used to find properties to your own keys You normally wouldn't use the class yourself. Instead, objects of this class will be created automatically from dictionaries, e.g. >>> mol.energy(map={"cutoff": 5*angstrom}) would automatically create a PropertyMap, and is equivalent to writing >>> mol.energy(map=create_map({"cutoff": 5*angstrom})) In the above case you are providing an extra "cutoff" option, and are passing the value "5*angstrom". You can also use the map to change the keys used to find properties, e.g. >>> mol.energy(map={"coordinates": "my_coords"}) would map the default "coordinates" property to your "my_coords" property. This means that the coordinates for the energy would be found at "my_coords" rather than "coordinates". You can map as many properties, and provide as many extra options as you want. """ifvaluesisNoneandextrasisNone:returnPropertyMap()elifvaluesisNone:returncreate_map(extras)try:map=PropertyMap(values)exceptException:map=NoneifmapisNone:wrapped_values={}forkey,valueinvalues.items():try:wrapped_values[key]=_Base.PropertyName(value)exceptException:try:wrapped_values[key]=_Base.PropertyName(wrap(value))exceptException:raiseValueError(f"Unable to set the property {key} to {value} ""because we cannot convert this to a C++ type.")map=PropertyMap(wrapped_values)ifextrasisnotNone:returnmap+create_map(extras)else:returnmap