PSCF v1.1
output.py
1"""! Module of parsers for PSCF output file formats. """
2
3import pscfpp.param as param
4import os
5
6# Contains classes Thermo, Species, State, and Sweep
7
8
136class Thermo:
137
138
148 def __init__(self, filename=None):
149 self.fHelmholtz = None
150 self.pressure = None
151 self.fIdeal = None
152 self.fInter = None
153 self.fExt = None
154 self.polymers = None
155 self.solvents = None
156 self.cellParams = None
157 self.tableLabel = None
158
159 if filename != None:
160 with open(filename) as f:
161 self.read(f)
162
163
171 def read(self, file):
172 line = self.skipEmptyLine(file)
173 l = line.split()
174 if l[0] != 'fHelmholtz':
175 raise Exception('Not valid Thermo file')
176 else:
177 self.fHelmholtz = float(l[1])
178 line = file.readline()
179 l = line.split()
180 self.pressure = float(l[1])
181 line = self.skipEmptyLine(file)
182
183 while line != '\n':
184 l = line.split()
185 if l[0] == 'fIdeal':
186 self.fIdeal = float(l[1])
187 if l[0] == 'fInter':
188 self.fInter = float(l[1])
189 if l[0] == 'fExt':
190 self.fExt = float(l[1])
191 line = file.readline()
192
193 line = self.skipEmptyLine(file)
194
195 while line != '\n':
196 if line == 'polymers:\n':
197 self.polymers = []
198 self.tableLabel = file.readline()
199 line = file.readline()
200 while line != '\n':
201 l = line.split()
202 self.polymers.append(Species(l))
203 line = file.readline()
204
205 if line == 'solvents:\n':
206 self.solvents = []
207 line = file.readline()
208 line = file.readline()
209 while line != '\n':
210 l = line.split()
211 self.solvents.append(Species(l))
212 line = file.readline()
213
214 if line == 'cellParams:\n':
215 self.cellParams = []
216 line = file.readline()
217 while line != '\n':
218 l = line.split()
219 self.cellParams.append(float(l[1]))
220 line = file.readline()
221
222 line = self.skipEmptyLine(file)
223
224 if line == '':
225 break
226
227
235 def skipEmptyLine(self, file):
236 line = file.readline()
237 while line == '\n':
238 line = file.readline()
239 return line
240
241
250 def write(self, filename):
251 with open(filename, 'w') as f:
252 f.write(self.__str__())
253
254
257 def __str__(self):
258 s = ''
259 s += 'fHelmholtz'
260 v = f'{self.fHelmholtz:.11e}'
261 s += f'{v:>22}\n'
262 s += 'pressure '
263 v = f'{self.pressure:.11e}'
264 s += f'{v:>22}\n'
265 s += '\n'
266
267 if (self.fIdeal != None) or (self.fInter != None) or (self.fExt != None):
268 if self.fIdeal != None:
269 s += 'fIdeal '
270 v = f'{self.fIdeal:.11e}'
271 s += f'{v:>22}\n'
272 if self.fInter != None:
273 s += 'fInter '
274 v = f'{self.fInter:.11e}'
275 s += f'{v:>22}\n'
276 if self.fExt != None:
277 s += 'fExt '
278 v = f'{self.fExt:.11e}'
279 s += f'{v:>22}\n'
280 s += '\n'
281
282 s += 'polymers:\n'
283 s += self.tableLabel
284 for i in range(len(self.polymers)):
285 p = f'{self.polymers[i].phi:.11e}'
286 m = f'{self.polymers[i].mu:.11e}'
287 s += f'{i:>5}{p:>20}{m:>20}\n'
288 s += '\n'
289
290 if self.solvents != None:
291 s += 'solvents:\n'
292 s += self.tableLabel
293 for i in range(len(self.solvents)):
294 p = f'{self.solvents[i].phi:.11e}'
295 m = f'{self.solvents[i].mu:.11e}'
296 s += f'{i:>5}{p:>20}{m:>20}\n'
297 s += '\n'
298
299 if self.cellParams != None:
300 s += 'cellParams:\n'
301 for i in range(len(self.cellParams)):
302 v = f'{self.cellParams[i]:.11e}'
303 s += f'{i:>5}{v:>20}\n'
304 s += '\n'
305
306 s += '\n'
307
308 return s
309
310
317
318
323 def __init__(self, l):
324 if len(l) == 3:
325 self.phi = float(l[1])
326 self.mu = float(l[2])
327 if len(l) == 2:
328 self.phi = float(l[0])
329 self.mu = float(l[1])
330
331
332
333
398class State:
399
400
405 def __init__(self, filename):
406 with open(filename) as f:
407 firstline = f.readline()
408 fl = firstline.split()
409 if fl[0] != 'System{':
410 raise Exception('Not valid State file')
411 else:
412 self.param = param.Composite(f, 'System')
413 self.thermo = Thermo()
414 self.thermo.read(f)
415
416
423 def __str__(self):
424 out = self.param.__str__() + '\n' + self.thermo.__str__()
425 return out
426
427
435 def write(self, filename):
436 with open(filename) as f:
437 f.write(self.__str__())
438
439
440
483class Sweep:
484
485
492 def __init__(self, prefix):
493 self.sweep = []
494 num = 0
495 filename = prefix + str(num) + '.stt'
496 while os.path.isfile(filename) == True:
497 s = State(filename)
498 self.sweep.append(s)
499 num += 1
500 filename = prefix + str(num) + '.stt'
501
502
573 def summary(self, vars, index = False):
574 n = len(vars)
575
576 summary = []
577
578 for i in range(0, len(self.sweep)):
579 if index == True:
580 s = [i]
581 else:
582 s = []
583 for j in range(0, n):
584 a = self.sweep[i]
585 string = 'a.' + vars[j]
586 try:
587 val = eval(string)
588 except RecursionError:
589 raise Exception('Wrong command or values do not exist')
590 s.append(val)
591 summary.append(s)
592
593 return summary
594
595
596
627 def summaryString(self, vars):
628 n = len(vars)
629
630 summary = []
631
632 for i in range(0, len(self.sweep)):
633 s = [i]
634 for j in range(0, n):
635 a = self.sweep[i]
636 string = 'a.' + vars[j]
637 try:
638 val = eval(string)
639 except RecursionError:
640 raise Exception('Wrong command or values do not exist')
641 s.append(val)
642 summary.append(s)
643
644 nl = [4]
645 nameList = ['step']
646 for i in range(0, n):
647 index = vars[i].rfind('.')
648 name = vars[i][index+1:]
649 nameList.append(name)
650 nl.append(len(name))
651
652 valType = []
653 for i in range(0, len(summary)):
654 valType.append([])
655 for j in range(0, len(summary[0])):
656 valType[i].append(type(summary[i][j]))
657
658 for i in range(0, len(summary)):
659 for j in range(0, len(summary[0])):
660 length = len(str(summary[i][j]))
661 if (valType[i][j] == str) and (length > nl[j]):
662 nl[j] = length
663 if (valType[i][j] == float) and (13 > nl[j]):
664 nl[j] = 13
665 if (valType[i][j] == int) and (length > nl[j]):
666 nl[j] = length
667
668
669 summaryString = ' '
670 for i in range(0, len(nameList)):
671 stringFormat = '{:>' + str(nl[i]) + 's}'
672 if i != len(nameList)-1:
673 summaryString += stringFormat.format(nameList[i]) + ' '
674 else:
675 summaryString += stringFormat.format(nameList[i]) + '\n '
676
677 for i in range(0, len(summary)):
678 for j in range(0, len(summary[0])):
679 if valType[i][j] == int:
680 stringFormat = '{:>' + str(nl[j]) + '}'
681 summaryString += stringFormat.format(summary[i][j])
682 if valType[i][j] == float:
683 stringFormat = '{:.7e}'
684 val = stringFormat.format(summary[i][j])
685 summaryString += val
686 if valType[i][j] == str:
687 stringFormat = '{:>' + str(nl[j]) + 's}'
688 summaryString += stringFormat.format(summary[i][j])
689 if j == len(summary[0])-1:
690 summaryString += '\n '
691 else:
692 summaryString += ' '
693
694 return summaryString
695
696
701 def __getitem__(self, key):
702 return self.sweep[key]
703
704
707 def __len__(self):
708 return len(self.sweep)
709
Container for phi and mu for a single species in a Thermo object.
Definition: output.py:316
def __init__(self, l)
Constructor.
Definition: output.py:323
Container for data in state files produced by a sweep.
Definition: output.py:398
def write(self, filename)
Write the contents of this object to file in state file format.
Definition: output.py:435
def __str__(self)
Return string representation of this object in state file format.
Definition: output.py:423
def __init__(self, filename)
Constructor.
Definition: output.py:405
Container for data in state files produced by a PSCF sweep.
Definition: output.py:483
def __len__(self)
Get the number of states in a sweep.
Definition: output.py:707
def __init__(self, prefix)
Constructor.
Definition: output.py:492
def __getitem__(self, key)
Get a specific State object, specified by integer index.
Definition: output.py:701
def summaryString(self, vars)
Return a summary report as a formatted string suitable for printing.
Definition: output.py:627
def summary(self, vars, index=False)
Make a summary report containing values for selected variables.
Definition: output.py:573
Parser and container for PSCF thermo file blocks.
Definition: output.py:136
def write(self, filename)
Write the contents of this object in thermo file format to a file.
Definition: output.py:250
def read(self, file)
Read the passed-in open-file.
Definition: output.py:171
def __str__(self)
Return a string representation of this object in thermo file format.
Definition: output.py:257
def skipEmptyLine(self, file)
Skip empty lines in the file.
Definition: output.py:235
def __init__(self, filename=None)
Constructor.
Definition: output.py:148
Container for data of a Composite in a param file.
Definition: param.py:197
Module for parsing param files.
Definition: param.py:1