1+ import os
12from importlib import reload
3+ from typing import Any
24
5+ import numpy as np
36from nomad .datamodel import EntryArchive
47from nomad .parsing .file_parser import ArchiveWriter
58from nomad .parsing .file_parser .mapping_parser import MetainfoParser , TextParser
811from nomad_simulations .schema_packages .general import Program , Simulation
912from structlog .stdlib import BoundLogger
1013
14+ from nomad_simulation_parsers .parsers .utils .general import search_files
1115from nomad_simulation_parsers .schema_packages import ams
1216
1317from .file_parser import OutParser
18+ from .file_parser import RKFParser as RKFTextParser
1419
1520LOGGER = get_logger (__name__ )
1621
@@ -21,6 +26,44 @@ class MainfileParser(TextParser):
2126 def logger (self ):
2227 return LOGGER
2328
29+ def get_xc_functionals (self , source : dict [str , Any ]) -> list [str ]:
30+ xc_functionals = []
31+ for xc_type in ['LDA' , 'GGA' , 'MGGA' ]:
32+ functionals = source .get (xc_type , '' ).split ()
33+ kind = ['XC' ] if len (functionals ) == 1 else ['X' , 'C' ]
34+ for n , functional in enumerate (functionals ):
35+ xc_functionals .append (
36+ f'{ xc_type } _{ kind [n ]} _{ functional .rstrip ("x" ).rstrip ("c" ).upper ()} '
37+ )
38+ return xc_functionals
39+
40+ def get_contributions (self , source : dict [str , Any ]) -> list [dict [str , Any ]]:
41+ return [
42+ dict (name = key , value = val ) for key , val in source .items () if val is not None
43+ ]
44+
45+ def get_eigenvalues (
46+ self , source : dict [str , Any ] | list [np .ndarray ]
47+ ) -> list [dict [str , np .ndarray ]]:
48+ energies = source .get ('energies' , []) if isinstance (source , dict ) else []
49+ occupations = (
50+ source .get ('occupations' , []) if isinstance (source , dict ) else source [2 ]
51+ )
52+ nspin = max (len (energies ), len (occupations ))
53+ eigenvalues = [dict () for _ in range (nspin )]
54+ for n , energy in enumerate (energies ):
55+ eigenvalues [n ]['eigenvalues' ] = energy
56+ for n , occupations in enumerate (occupations ):
57+ eigenvalues [n ]['occupations' ] = occupations
58+ return [eig for eig in eigenvalues if eig ]
59+
60+
61+ class RKFParser (MainfileParser ):
62+ # TODO temporary fix for structlog unable to propagate logger
63+ @property
64+ def logger (self ):
65+ return LOGGER
66+
2467
2568# TODO temporary fix for structlog unable to propagate logger
2669class AMSMetainfoParser (MetainfoParser ):
@@ -32,6 +75,7 @@ def logger(self):
3275class AMSArchiveWriter (ArchiveWriter ):
3376 mainfile_parser = MainfileParser (text_parser = OutParser ())
3477 metainfo_parser = AMSMetainfoParser ()
78+ rkf_parser = RKFParser (text_parser = RKFTextParser ())
3579
3680 def write_to_archive (self ):
3781 # reload schema package to use correct annotations
@@ -41,8 +85,17 @@ def write_to_archive(self):
4185 self .archive .data = Simulation (program = Program (name = 'AMS' ))
4286 self .metainfo_parser .data_object = self .archive .data
4387
44- self .mainfile_parser .filepath = self .mainfile
45- self .mainfile_parser .convert (self .metainfo_parser )
88+ rkf_files = search_files ('ams.rkf' , os .path .dirname (self .mainfile ))
89+ self .parser = self .mainfile_parser
90+ self .parser .filepath = self .mainfile
91+ if rkf_files :
92+ if len (rkf_files ) > 1 :
93+ self .logger .warning ('Multiple ams.rkf files found.' )
94+ self .parser = self .rkf_parser
95+ self .parser .filepath = rkf_files [0 ]
96+ self .parser .data_object .parse ()
97+
98+ self .parser .convert (self .metainfo_parser )
4699
47100
48101class AMSParser (MatchingParser ):
0 commit comments