-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathCalculator.py
160 lines (129 loc) · 4.91 KB
/
Calculator.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
"""
CoDE Calculator class
"""
from Structure import Structure
import importlib
class Calculator(object):
"""
Base class for calculators
"""
# Default calculators for properties.
# This will contain all types of structure and chart calculations
DEFAULT_ENGINE = {'XRD': 'ASE',
'SANS': 'ASE'}
def __init__(self, parent=None,
structure=None,
wavelength=None,
):
"""
The constructor takes structure and other properties.
This will define the state of the calculator.
Quick calculations with overriden properties can be performed
by calling calculate methods with extra arguments.
"""
self.parent = parent
# simple dictionary defining calculator state.
# Currently it only holds 'wavelength' for testing
self.parameters = {}
# Active calculator plugin. Can change depending on what needs to be evaluated
self.activePlugin = None
if structure is not None:
self.parameters['structure'] = structure
if wavelength is not None:
self.parameters['wavelength'] = wavelength
@property
def structure(self):
return self.parameters['structure']
@structure.setter
def structure(self, value):
self.parameters['structure'] = value
@property
def wavelength(self):
return self.parameters['wavelength']
@wavelength.setter
def wavelength(self, value):
self.parameters['wavelength'] = value
def loadPlugin(self, engine=""):
"""
Instantiate a 3rd party computational plugin
"""
# see if we have the right engine
if self.activePlugin is None or self.activePlugin.name() != engine:
self.activePlugin = self.createPlugin(engine)
def createPlugin(self, engine=""):
"""
Create an instance of a computational plugin, based on engine name.
"""
module_name = "CalcPlugin_"+engine
method_module = importlib.import_module(module_name)
method_to_call = getattr(method_module, module_name)
return method_to_call()
def calculateXRD(self, structure=None, engine="", wavelength=None):
"""
calculate simple diffraction pattern on atoms
"""
if not engine:
engine = self.DEFAULT_ENGINE['XRD']
self.loadPlugin(engine)
# Make sure the plugin can calculate this property
if not self.activePlugin.canCalculate('XRD'):
raise RuntimeError("Requested calculation engine can't be used to calculate XRD.")
# check the argument list
if structure is None:
if 'structure' not in self.parameters:
# no structure -> bail out
raise RuntimeError ("No active structure!")
else:
structure = self.parameters['structure']
if wavelength is None:
# check the Calculator dictionary
if 'wavelength' in self.parameters:
wavelength = self.parameters['wavelength']
# Fall back to default
if wavelength is None:
wavelength = 1.5405981
# call the XRD method on the ASE calculator plugin
result = self.activePlugin.getProperty('XRD', structure=structure, wavelength=wavelength)
return result
def calculateSANS(self, structure=None, engine="", wavelength=None):
"""
calculate simple diffraction pattern on atoms
"""
if not engine:
engine = self.DEFAULT_ENGINE['SANS']
self.loadPlugin(engine)
# Make sure the plugin can calculate this property
if not self.activePlugin.canCalculate('SANS'):
raise RuntimeError("Requested calculation engine can't be used to calculate SANS.")
# check the argument list
if structure is None:
if 'structure' not in self.parameters:
# no structure -> bail out
raise RuntimeError ("No active structure!")
else:
structure = self.parameters['structure']
if wavelength is None:
# check the Calculator dictionary
if 'wavelength' in self.parameters:
wavelength = self.parameters['wavelength']
# Fall back to default
if wavelength is None:
wavelength = 1.5405981
self.activePlugin.getProperty('SANS', structure=structure, wavelength=wavelength)
def calculateQPA(self, structure=None):
"""
Perform Quantitative Phase Analysis
"""
pass
def calculateCrystallinity(self, structure=None):
"""
Perform degree of crystallinity calculations
"""
pass
def __eq__(self, other):
"""
Default behaviour for =
"""
#if isinstance(other, Calculator):
# return self.number == other.number
return False