pyALF 2.5.post1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
py_alf/alf_source.py ADDED
@@ -0,0 +1,157 @@
1
+ """
2
+ Provides interfaces for compiling, running and postprocessing ALF in Python.
3
+ """
4
+ # pylint: disable=invalid-name
5
+ # pylint: disable=too-many-instance-attributes
6
+ # py lint: disable=consider-using-f-string
7
+
8
+ __author__ = "Jonas Schwab"
9
+ __copyright__ = "Copyright 2020-2024, The ALF Project"
10
+ __license__ = "GPL"
11
+
12
+ import os
13
+ import copy
14
+ import subprocess
15
+ from collections import OrderedDict
16
+ import importlib.util
17
+
18
+
19
+ class cd:
20
+ """Context manager for changing the current working directory."""
21
+
22
+ def __init__(self, directory):
23
+ self.directory = os.path.expanduser(directory)
24
+ self.saved_path = os.getcwd()
25
+
26
+ def __enter__(self):
27
+ os.chdir(self.directory)
28
+
29
+ def __exit__(self, exc_type, exc_val, exc_tb):
30
+ os.chdir(self.saved_path)
31
+
32
+
33
+ class ALF_source:
34
+ """
35
+ Objet representing ALF source code.
36
+
37
+ Parameters
38
+ ----------
39
+ alf_dir : path-like object, default=os.getenv('ALF_DIR', './ALF')
40
+ Directory containing the ALF source code. If the directory does
41
+ not exist, the source code will be fetched from a server.
42
+ Defaults to environment variable $ALF_DIR if defined, otherwise
43
+ to './ALF'.
44
+ branch : str, optional
45
+ If specified, this will be checked out by git.
46
+ url : str, default='https://git.physik.uni-wuerzburg.de/ALF/ALF.git'
47
+ Address from where to clone ALF if alf_dir does not exist.
48
+ """
49
+
50
+ def __init__(self, alf_dir=os.getenv('ALF_DIR', './ALF'), branch=None,
51
+ url='https://git.physik.uni-wuerzburg.de/ALF/ALF.git'):
52
+ self.alf_dir = os.path.abspath(os.path.expanduser(alf_dir))
53
+ self.branch = branch
54
+
55
+ if not os.path.exists(self.alf_dir):
56
+ print("Repository {} does not exist, cloning from {}"
57
+ .format(alf_dir, url))
58
+ try:
59
+ subprocess.run(["git", "clone", url, self.alf_dir], check=True)
60
+ except subprocess.CalledProcessError as git_clone_failed:
61
+ raise RuntimeError('Error while cloning repository') \
62
+ from git_clone_failed
63
+ if branch is not None:
64
+ with cd(self.alf_dir):
65
+ print('Checking out branch {}'.format(branch))
66
+ try:
67
+ subprocess.run(['git', 'checkout', branch], check=True)
68
+ except subprocess.CalledProcessError as git_checkout_failed:
69
+ raise RuntimeError(
70
+ 'Error while checking out {}'.format(branch)) \
71
+ from git_checkout_failed
72
+
73
+ def import_module(module_name, path):
74
+ """Dynamically import module from given path."""
75
+ spec = importlib.util.spec_from_file_location(module_name, path)
76
+ module = importlib.util.module_from_spec(spec)
77
+ spec.loader.exec_module(module)
78
+ return module
79
+
80
+ try:
81
+ parse_ham_mod = import_module(
82
+ 'parse_ham',
83
+ os.path.join(self.alf_dir, 'Prog', 'parse_ham_mod.py'))
84
+ except FileNotFoundError as parse_ham_not_found:
85
+ raise FileNotFoundError(
86
+ "parse_ham_mod.py not found. "
87
+ "Directory {} ".format(self.alf_dir) +
88
+ "does not contain a supported ALF code.") \
89
+ from parse_ham_not_found
90
+ try:
91
+ default_parameters_generic = import_module(
92
+ 'default_parameters_generic',
93
+ os.path.join(self.alf_dir, 'Prog',
94
+ 'default_parameters_generic.py'))
95
+ except FileNotFoundError as default_parameters_generic_not_found:
96
+ raise FileNotFoundError(
97
+ "default_parameters_generic.py not found. "
98
+ "Directory {} ".format(self.alf_dir) +
99
+ "does not contain a supported ALF code.") \
100
+ from default_parameters_generic_not_found
101
+
102
+ self._PARAMS_GENERIC = default_parameters_generic._PARAMS_GENERIC
103
+
104
+ self.default_parameters = get_default_parameters(parse_ham_mod, self.alf_dir)
105
+
106
+ def get_ham_names(self):
107
+ """Return list of Hamiltonians."""
108
+ return list(self.default_parameters)
109
+
110
+ def get_default_params(self, ham_name, include_generic=True):
111
+ """Return full set of default parameters for hamiltonian."""
112
+ params = OrderedDict()
113
+ for nlist_name, nlist in self.default_parameters[ham_name].items():
114
+ params[nlist_name] = copy.deepcopy(nlist)
115
+ if include_generic:
116
+ for nlist_name, nlist in self._PARAMS_GENERIC.items():
117
+ params[nlist_name] = copy.deepcopy(nlist)
118
+ return params
119
+
120
+ def get_params_names(self, ham_name, include_generic=True):
121
+ """Return list of parameter names for hamiltonian,
122
+ transformed in all uppercase.
123
+ """
124
+ p_list = []
125
+ for nlist_name, nlist in self.default_parameters[ham_name].items():
126
+ p_list += list(nlist)
127
+ if include_generic:
128
+ for nlist_name in self._PARAMS_GENERIC:
129
+ p_list += list(self._PARAMS_GENERIC[nlist_name])
130
+
131
+ return [i.upper() for i in p_list]
132
+
133
+ def get_default_parameters(parse_ham_mod, alf_dir):
134
+ """Return dictionary of all default parameters of Hamiltonians.
135
+ By parsing Hamiltonians."""
136
+ try:
137
+ ham_names, ham_files = parse_ham_mod.get_ham_names_ham_files(
138
+ os.path.join(alf_dir, 'Prog', 'Hamiltonians.list')
139
+ )
140
+ ham_files = [os.path.join(alf_dir, 'Prog', ham_file) for
141
+ ham_file in ham_files]
142
+ except AttributeError:
143
+ # Backwards compatibility fallback
144
+ with open(os.path.join(alf_dir, 'Prog', 'Hamiltonians.list'),
145
+ 'r', encoding='UTF-8') as f:
146
+ ham_names = f.read().splitlines()
147
+ ham_files = [os.path.join(
148
+ alf_dir, 'Prog', 'Hamiltonians',
149
+ 'Hamiltonian_{}_smod.F90'.format(ham_name)) for
150
+ ham_name in ham_names]
151
+
152
+ default_parameters = {}
153
+ for ham_name, ham_file in zip(ham_names, ham_files):
154
+ # print('Hamiltonian:', ham_name)
155
+ default_parameters[ham_name] = parse_ham_mod.parse(ham_file)
156
+ # pprint.pprint(self.default_parameters[ham_name])
157
+ return default_parameters