<s> import json <EOL> import numpy as np <EOL> import h5py <EOL> from larch import Group , Parameter , isParameter <EOL> from larch import ValidateLarchPlugin <EOL> from larch . utils import fixName <EOL> class H5PySaveFile ( object ) : <EOL> def __init__ ( self , fname , _larch = None ) : <EOL> self . fname = fname <EOL> self . _larch = _larch <EOL> self . symtable = _larch . symtable <EOL> self . isgroup = _larch . symtable . isgroup <EOL> self . _searched = [ ] <EOL> self . _subgroups = [ ] <EOL> self . _ids = [ ] <EOL> self . _objs = [ ] <EOL> self . out = { } <EOL> def search ( self , group ) : <EOL> """<STR_LIT>""" <EOL> if len ( self . _ids ) == <NUM_LIT:0> : <EOL> return <EOL> for nam in dir ( group ) : <EOL> self . _searched . append ( group ) <EOL> obj = getattr ( group , nam ) <EOL> if ( id ( obj ) in self . _ids and <EOL> obj not in self . out . values ( ) ) : <EOL> self . out [ nam ] = obj <EOL> self . _ids . remove ( id ( obj ) ) <EOL> self . _objs . remove ( obj ) <EOL> if ( self . isgroup ( obj ) and <EOL> obj not in self . _searched and <EOL> obj not in self . _subgroups ) : <EOL> self . _subgroups . append ( obj ) <EOL> if group in self . _subgroups : <EOL> self . _subgroups . remove ( group ) <EOL> for group in self . _subgroups : <EOL> self . search ( group ) <EOL> def add_h5group ( self , group , name , dat = None , attrs = None ) : <EOL> """<STR_LIT>""" <EOL> g = group . create_group ( name ) <EOL> if isinstance ( dat , dict ) : <EOL> for key , val in dat . items ( ) : <EOL> g [ key ] = val <EOL> if isinstance ( attrs , dict ) : <EOL> for key , val in attrs . items ( ) : <EOL> g . attrs [ key ] = val <EOL> return g <EOL> def add_h5dataset ( self , group , name , data , attrs = None , ** kws ) : <EOL> """<STR_LIT>""" <EOL> kwargs = { } <EOL> if isinstance ( data , np . ndarray ) : <EOL> kwargs = { '<STR_LIT>' : <NUM_LIT:4> } <EOL> kwargs . update ( kws ) <EOL> try : <EOL> d = group . create_dataset ( name , data = data , ** kwargs ) <EOL> except TypeError : <EOL> d = group . create_dataset ( name , data = repr ( data ) , ** kwargs ) <EOL> if isinstance ( attrs , dict ) : <EOL> for key , val in attrs . items ( ) : <EOL> d . attrs [ key ] = val <EOL> return d <EOL> def add_data ( self , group , name , data ) : <EOL> if self . isgroup ( data ) : <EOL> g = self . add_h5group ( group , name , <EOL> attrs = { '<STR_LIT>' : '<STR_LIT>' , <EOL> '<STR_LIT:class>' : data . __class__ . __name__ } ) <EOL> for comp in dir ( data ) : <EOL> self . add_data ( g , comp , getattr ( data , comp ) ) <EOL> elif isinstance ( data , ( list , tuple ) ) : <EOL> dtype = '<STR_LIT:list>' <EOL> if isinstance ( data , tuple ) : dtype = '<STR_LIT>' <EOL> g = self . add_h5group ( group , name , attrs = { '<STR_LIT>' : dtype } ) <EOL> for ix , comp in enumerate ( data ) : <EOL> iname = '<STR_LIT>' % ix <EOL> self . add_data ( g , iname , comp ) <EOL> elif isinstance ( data , dict ) : <EOL> g = self . add_h5group ( group , name , attrs = { '<STR_LIT>' : '<STR_LIT>' } ) <EOL> for key , val in data . items ( ) : <EOL> self . add_data ( g , key , val ) <EOL> elif isParameter ( data ) : <EOL> g = self . add_h5group ( group , name , attrs = { '<STR_LIT>' : '<STR_LIT>' } ) <EOL> self . add_h5dataset ( g , '<STR_LIT>' , data . asjson ( ) ) <EOL> else : <EOL> d = self . add_h5dataset ( group , name , data ) <EOL> def save ( self , * args ) : <EOL> self . _ids = [ id ( a ) for a in args ] <EOL> self . _objs = list ( args ) <EOL> self . search ( self . symtable ) <EOL> self . fh = h5py . File ( self . fname , '<STR_LIT:a>' ) <EOL> try : <EOL> self . fh . attrs [ '<STR_LIT>' ] = '<STR_LIT>' <EOL> self . fh . attrs [ '<STR_LIT:version>' ] = '<STR_LIT>' <EOL> except : <EOL> pass <EOL> for nam , obj in self . out . items ( ) : <EOL> try : <EOL> self . add_data ( self . fh , nam , obj ) <EOL> except : <EOL> print ( '<STR_LIT>' , nam ) <EOL> for obj in self . _objs : <EOL> nam = getattr ( obj , '<STR_LIT>' , hex ( id ( obj ) ) ) <EOL> nam = fixName ( nam , allow_dot = False ) <EOL> if nam . startswith ( '<STR_LIT>' ) : <EOL> nam = '<STR_LIT>' % nam [ <NUM_LIT:2> : ] <EOL> try : <EOL> self . add_data ( self . fh , nam , obj ) <EOL> except : <EOL> print ( '<STR_LIT>' , nam ) <EOL> self . fh . close ( ) <EOL> @ ValidateLarchPlugin <EOL> def save ( fname , * args , ** kws ) : <EOL> """<STR_LIT>""" <EOL> _larch = kws . get ( '<STR_LIT>' , None ) <EOL> saver = H5PySaveFile ( fname , _larch = _larch ) <EOL> saver . save ( * args ) <EOL> @ ValidateLarchPlugin <EOL> def restore ( fname , group = None , _larch = None ) : <EOL> """<STR_LIT>""" <EOL> symtable = _larch . symtable <EOL> msg = _larch . writer . write <EOL> fh = h5py . File ( fname , '<STR_LIT:r>' ) <EOL> if fh . attrs . get ( '<STR_LIT>' , None ) != '<STR_LIT>' : <EOL> msg ( "<STR_LIT>" % fname ) <EOL> return <EOL> create_group = _larch . symtable . create_group <EOL> from larch_plugins . xafs import ( FeffPathGroup , FeffDatFile , <EOL> FeffitDataSet , TransformGroup ) <EOL> def make_group ( h5group ) : <EOL> creators = { '<STR_LIT>' : TransformGroup , <EOL> '<STR_LIT>' : FeffDatFile , <EOL> '<STR_LIT>' : FeffitDataSet , <EOL> '<STR_LIT>' : FeffPathGroup } <EOL> gtype = h5group . attrs . get ( '<STR_LIT:class>' , None ) <EOL> return creators . get ( gtype , create_group ) ( _larch = _larch ) <EOL> def get_component ( val ) : <EOL> if isinstance ( val , h5py . Group ) : <EOL> ltype = val . attrs . get ( '<STR_LIT>' , None ) <EOL> if ltype == '<STR_LIT>' : <EOL> me = make_group ( val ) <EOL> for skey , sval in val . items ( ) : <EOL> setattr ( me , skey , get_component ( sval ) ) <EOL> return me <EOL> elif ltype == '<STR_LIT>' : <EOL> kws = json . loads ( val [ '<STR_LIT>' ] . value ) <EOL> if kws [ '<STR_LIT>' ] is not None : <EOL> kws . pop ( '<STR_LIT>' ) <EOL> kws [ '<STR_LIT>' ] = _larch <EOL> return Parameter ( ** kws ) <EOL> elif ltype in ( '<STR_LIT:list>' , '<STR_LIT>' ) : <EOL> me = [ ] <EOL> for skey , sval in val . items ( ) : <EOL> me . append ( get_component ( sval ) ) <EOL> if ltype == '<STR_LIT>' : <EOL> me = tuple ( me ) <EOL> return me <EOL> elif ltype == '<STR_LIT>' : <EOL> me = { } <EOL> for skey , sval in val . items ( ) : <EOL> me [ skey ] = get_component ( sval ) <EOL> return me <EOL> elif isinstance ( val , h5py . Dataset ) : <EOL> return val . value <EOL> if group is None : <EOL> group = create_group ( ) <EOL> for key , val in fh . items ( ) : <EOL> setattr ( group , key , get_component ( val ) ) <EOL> fh . close ( ) <EOL> return group <EOL> def registerLarchPlugin ( ) : <EOL> return ( '<STR_LIT>' , { '<STR_LIT>' : save , '<STR_LIT>' : restore } ) </s>
