1################################################################## 2## (c) Copyright 2015- by Jaron T. Krogel ## 3################################################################## 4 5 6#====================================================================# 7# nexus_base.py # 8# Provides base class functionality and access to 'global' data # 9# for core Nexus classes. # 10# # 11# Content summary: # 12# NexusCore # 13# Base class for core Nexus classes. # 14# Data intended to be 'global' among core classes is assigned # 15# by the Settings class. # 16# # 17# nexus_core # 18# Namespace to be accessed by core Nexus classes. # 19# These are classes that inherit from NexusCore directly. # 20# # 21# nexus_noncore # 22# Namespace to be accessed in read-only fashion by non-core # 23# classes. # 24# # 25#====================================================================# 26 27 28import os 29import traceback 30import gc as garbage_collector 31from versions import nexus_version 32from memory import resident 33from generic import obj 34from developer import DevBase,log 35 36 37# Nexus namespaces 38# nexus_core: to be used by NexusCore classes only 39# nexus_noncore: allows read only access to some nexus_core data to non-core classes 40nexus_core = obj() 41nexus_noncore = obj() 42nexus_core_noncore = obj() 43 44status_modes = obj( 45 none = 0, 46 standard = 1, 47 active = 2, 48 failed = 3, 49 ready = 4, 50 ) 51 52modes = obj( 53 none = 0, 54 setup = 1, 55 send_files = 2, 56 submit = 3, 57 get_output = 4, 58 analyze = 5, 59 stages = 6, 60 all = 7 61 ) 62 63garbage_collector.enable() 64 65 66nexus_noncore_defaults = obj( 67 basis_dir = None, 68 basissets = None, 69 ) 70 71# core namespace elements that can be accessed by noncore classes 72nexus_core_noncore_defaults = obj( 73 pseudo_dir = None, # used by: Settings, VaspInput 74 pseudopotentials = None, # used by: Simulation, GamessInput 75 ) 76 77nexus_core_defaults = obj( 78 status_only = False, # used by: ProjectManager 79 generate_only = False, # used by: Simulation,Machine 80 sleep = 3, # used by: ProjectManager 81 runs = 'runs', # used by: Simulation,Machine 82 results = '', # used by: Simulation 83 local_directory = './', # used by: Simulation,Machine 84 remote_directory = './', # used by: Simulation 85 file_locations = ['./'], # used by: Simulation 86 monitor = True, # used by: ProjectManager,Simulation,Machine 87 skip_submit = False, # used by: Simulation 88 load_images = True, # used by: ProjectManager 89 modes = modes, # used by: ProjectManager,Simulation 90 mode = modes.stages, # used by: Simulation 91 stages_set = set(), # used by: ProjectManager,Simulation 92 stages = [], # used by: Simulation 93 primary_modes = ['setup','send_files','submit','get_output','analyze'], # used by: Settings 94 dependent_modes = set(['submit']), # used by: ProjectManager,Simulation 95 verbose = True, # used by: NexusCore 96 debug = False, # used by: NexusCore 97 trace = False, # used by: NexusCore 98 indent = ' ', # used by: NexusCore 99 status_modes = status_modes, # used by: ProjectManager 100 status = status_modes.none, # used by: ProjectManager 101 emulate = False, # unused 102 progress_tty = False, # used by: ProjectManager 103 graph_sims = False, # used by: ProjectManager 104 command_line = True, # used by: Settings 105 **nexus_core_noncore_defaults 106 ) 107 108def restore_nexus_core_defaults(): 109 nexus_core.clear() 110 nexus_noncore.clear() 111 nexus_core_noncore.clear() 112 113 nexus_core.set(**nexus_core_defaults.copy()) 114 nexus_noncore.set(**nexus_noncore_defaults.copy()) 115 nexus_core_noncore.transfer_from(nexus_core,keys=list(nexus_core_noncore_defaults.keys())) 116#end def restore_nexus_core_defaults 117 118restore_nexus_core_defaults() 119 120 121nexus_core_no_process = set(''' 122 status_only generate_only sleep 123 '''.split()) 124 125 126class NexusCore(DevBase): 127 128 # garbage collector 129 gc = garbage_collector 130 131 # mutable/dynamic nexus core data 132 wrote_something = False # for pretty printing 133 working_directory = None 134 wrote_splash = False 135 136 @staticmethod 137 def write_splash(): 138 if not NexusCore.wrote_splash: 139 splash_text = ''' 140_____________________________________________________ 141 142 Nexus {}.{}.{} 143 144 (c) Copyright 2012- Nexus developers 145 146 Please cite: 147 J. T. Krogel Comput. Phys. Commun. 198 154 (2016) 148 https://doi.org/10.1016/j.cpc.2015.08.012 149_____________________________________________________ 150 151 '''.format(*nexus_version) 152 log(splash_text) 153 NexusCore.wrote_splash = True 154 #end if 155 #end def write_splash 156 157 @staticmethod 158 def write_end_splash(): 159 return # don't do this yet 160 splash_text = ''' 161_____________________________________________________ 162_____________________________________________________ 163 ''' 164 print(splash_text) 165 #end def write_end_splash 166 167 def mem_usage(self): 168 return int(resident()/1e6) 169 #end def mem_usage 170 171 def log(self,*texts,**kwargs): 172 """Write output to log file. 173 Keyword arguments 174 n - spaces to indent 175 progress - if True and output is to a terminal, overwrite and 176 update the last line, rather than scrolling. 177 """ 178 if nexus_core.verbose: 179 if len(kwargs)>0: 180 n = kwargs['n'] 181 else: 182 n=0 183 #end if 184 is_progress = kwargs.get('progress',False) 185 text='' 186 for t in texts: 187 text+=str(t)+' ' 188 #end for 189 pad = n*nexus_core.indent 190 output_text = pad+text.replace('\n','\n'+pad) 191 if nexus_core.progress_tty and is_progress and self._logfile.isatty(): 192 # spaces to ensure previous line is overwritten. Need better solution. 193 self._logfile.write(output_text+' \r') 194 self._logfile.flush() 195 else: 196 self._logfile.write(output_text+'\n') 197 #end if 198 NexusCore.wrote_something = True 199 #end def log 200 201 def dlog(self,*texts,**kwargs): 202 if nexus_core.debug: 203 #self.log('mem_usage',self.mem_usage(),n=5) 204 self.log(*texts,**kwargs) 205 #end if 206 #end def dlog 207 208 def tlog(self,*texts,**kwargs): 209 if nexus_core.trace: 210 self.log(*texts,**kwargs) 211 w,s,j,f,g,a=int(self.setup),int(self.submitted),int(self.job.finished),int(self.finished),int(self.got_output),int(self.analyzed) 212 self.log('w,s,j,f,g,a',w,s,j,f,g,a,n=kwargs['n']+1) 213 #self.log('dependencies',self.dependencies.keys(),n=kwargs['n']+1) 214 #self.log('dependents ',self.dependents.keys(),n=kwargs['n']+1) 215 #end if 216 #end def tlog 217 218 def enter(self,directory,changedir=True,msg=''): 219 NexusCore.working_directory = os.getcwd() 220 self.log(' Entering '+directory,msg) 221 if changedir: 222 os.chdir(directory) 223 #end if 224 pad = ' ' 225 return pad 226 #end def enter 227 228 def leave(self): 229 os.chdir(NexusCore.working_directory) 230 #end def leave 231#end class NexusCore 232