Source code for triqs_tprf.ParameterCollection

# -*- coding: utf-8 -*-

################################################################################
#
# TPRF: Two-Particle Response Function (TPRF) Toolbox for TRIQS
#
# Copyright (C) 2017 by Hugo U.R. Strand
# Copyright (C) 2019 by S.Käser 
# Author: H. U.R. Strand, S. Käser
#
# TPRF is free software: you can redistribute it and/or modify it under the
# terms of the GNU General Public License as published by the Free Software
# Foundation, either version 3 of the License, or (at your option) any later
# version.
#
# TPRF is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
# details.
#
# You should have received a copy of the GNU General Public License along with
# TPRF. If not, see <http://www.gnu.org/licenses/>.
#
################################################################################

import inspect
import itertools
import numpy as np

# ----------------------------------------------------------------------
[docs] class ParameterCollection(object): """ Helper class for handing collections of parameters. Parameters ---------- kwargs : dict Key-word argument list of parameters. Examples -------- A ``ParameterCollection`` has any number of attributes, accessible with the dot operator. >>> p = ParameterCollection(beta=10., U=1.0, t=1.0) >>> print p U = 1.0 beta = 10.0 t = 1.0 >>> print p.beta 10.0 >>> p.W = 1.2 >>> print p U = 1.0 W = 1.2 beta = 10.0 t = 1.0 and can be stored and loaded to/from TRIQS hdf archives. >>> from h5 import HDFArchive >>> with HDFArchive('data.h5', 'w') as arch: arch['p'] = p >>> with HDFArchive('data.h5', 'r') as arch: p_ref = arch['p'] >>> print p_ref U = 1.0 beta = 10.0 t = 1.0 """ def __init__(self, **kwargs): self.__dict__.update(kwargs) def items(self): return list(self.__dict__.items()) def keys(self): return list(self.__dict__.keys()) def dict(self): return self.__dict__
[docs] def alter(self, **kwargs): """Change or add attributes Returns ------- p : ``ParameterCollection`` """ p = self.copy() p.__dict__.update(kwargs) return p
[docs] def copy(self): """Shallow copy """ p = ParameterCollection(**self.dict()) return p
def __getitem__(self, key): return self.__dict__[key] def __reduce_to_dict__(self): return self.__dict__ def _clean_bools(self): """ Fix for bug in Triqs that cast bool to numpy.bool_ here we cast all numpy.bools_ to plain python bools """ for key, value in list(self.items()): if type(value) == np.bool_: self.dict()[key] = bool(value)
[docs] def convert_keys_from_string_to_python(self, dict_key): """ h5.HDFArchive incorrectly mangles tuple keys to string running this on the affected dict tries to revert this by running eval on the string representation. UGLY FIX... """ d = self.dict()[dict_key] d_fix = {} for key, value in list(d.items()): d_fix[eval(key)] = value self.dict()[dict_key] = d_fix
def grab_attribs(self, obj, keys): for key in keys: val = getattr(obj, key) self.dict()[key] = val @classmethod def __factory_from_dict__(cls, name, d): ret = cls() ret.__dict__.update(d) ret._clean_bools() return ret def __str__(self): out = '' keys = np.sort(list(self.__dict__.keys())) # sort keys for key in keys: value = self.__dict__[key] if type(value) is ParameterCollection: pc_list = str(value).splitlines() pc_txt = ''.join([ key + '.' + row + '\n' for row in pc_list ]) out += pc_txt else: str_value = str(value) # Cut things that take more than five rows str_value_lines = str_value.splitlines() max_lines = 10 if len(str_value_lines) > max_lines: str_value = '\n'.join(str_value_lines[:max_lines] + ['...']) out += ''.join([key, ' = ', str_value]) + '\n' return out __repr__ = __str__ def get_my_name(self): ans = [] frame = inspect.currentframe().f_back tmp = dict(list(frame.f_globals.items()) + list(frame.f_locals.items())) for k, var in list(tmp.items()): if isinstance(var, self.__class__): if hash(self) == hash(var): ans.append(k) return ans
# -- Register ParameterCollection in Triqs formats from h5.formats import register_class register_class(ParameterCollection) # ----------------------------------------------------------------------
[docs] class ParameterCollections(object): r""" Helper class for handing a series of collections of parameters. Parameters ---------- objects : list List of ``ParameterCollection`` instances. Examples -------- The ``ParameterCollections`` class makes it easy to get vectors of parameters from a list of ``ParameterCollection`` objects. >>> p1 = ParameterCollection(beta=10., U=1.0, t=1.0) >>> p2 = ParameterCollection(beta=5., U=2.0, t=1.337) >>> ps = ParameterCollections(objects=[p1, p2]) >>> print ps.beta [10. 5.] >>> print ps.U [1. 2.] """ def __init__(self, objects=[]): self.objects = objects def append(self, obj): self.objects.append(obj) def sort_on(self, attr): val = self.getattr_from_objects(attr) sidx = np.argsort(val) self.set_sorted_order(sidx) def set_sorted_order(self, sorted_idx): sidx = np.array(sorted_idx) self.objects = list(np.array(self.objects)[sidx]) def getattr_from_objects(self, attr): return np.array([getattr(o, attr, None) for o in self.objects ]) def __getattr__(self, attr): if attr not in self.objects[0].keys(): raise AttributeError return self.getattr_from_objects(attr) def __reduce_to_dict__(self): return self.__dict__ @classmethod def __factory_from_dict__(cls, name, d): ret = cls(d['objects']) return ret def __iter__(self): return self.objects.__iter__() def __next__(self): return self.objects.__next__() def __getitem__(self, idx): return self.objects[idx] def __str__(self): out = '' for p in self: out += p.__str__() out += '\n' return out __repr__ = __str__
# ---------------------------------------------------------------------- # -- Register ParameterCollection in Triqs formats from h5.formats import register_class register_class(ParameterCollections) # ----------------------------------------------------------------------
[docs] def parameter_scan(p, **kwargs): """Return ParameterCollections with copies of ParameterCollection for different parameters Uses a given ParameterCollection as a template to create copies of it with one or more parameters changing. Stores all of these copies in a ParameterCollections for easy access. Parameters ---------- p : ParameterCollection, The ParameterCollection that shall be used as a template for all the others **kwargs : Sequence, The keyword gives the parameter name and the Sequence the values that shall be scanned through. Returns ------- ParameterCollections Examples -------- >>> p = ParameterCollection(beta=10., U=1.0, t=1.0) >>> ps = parameter_scan(p, U=[1.0, 1.5, 2.0]) >>> print ps[0] U = 1.0 beta = 10.0 t = 1.0 >>> print ps[1] U = 1.5 beta = 10.0 t = 1.0 >>> print ps[2] U = 2.0 beta = 10.0 t = 1.0 """ parameter_values = [] for key, value in kwargs.items(): parameter_values.append(zip([key]*len(value), value)) ps = [] for parameter_value in itertools.product(*parameter_values): ps.append(p.alter(**dict(parameter_value))) return ParameterCollections(ps)