1 # -*- coding: utf-8 -*-
3 # Copyright (C) 2008-2021 EDF R&D
5 # This library is free software; you can redistribute it and/or
6 # modify it under the terms of the GNU Lesser General Public
7 # License as published by the Free Software Foundation; either
8 # version 2.1 of the License.
10 # This library is distributed in the hope that it will be useful,
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 # Lesser General Public License for more details.
15 # You should have received a copy of the GNU Lesser General Public
16 # License along with this library; if not, write to the Free Software
17 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 # See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
21 # Author: Jean-Philippe Argaud, jean-philippe.argaud@edf.fr, EDF R&D
24 Informations sur le code et la plateforme, et mise à jour des chemins
26 La classe "PlatformInfo" permet de récupérer les informations générales sur
27 le code et la plateforme sous forme de strings, ou d'afficher directement
28 les informations disponibles par les méthodes. L'impression directe d'un
29 objet de cette classe affiche les informations minimales. Par exemple :
31 print(PlatformInfo().getVersion())
32 created = PlatformInfo().getDate()
34 La classe "PathManagement" permet de mettre à jour les chemins système pour
35 ajouter les outils numériques, matrices... On l'utilise en instanciant
36 simplement cette classe, sans meme récupérer d'objet :
39 La classe "SystemUsage" permet de sous Unix les différentes tailles
40 mémoires du process courant. Ces tailles peuvent être assez variables et
41 dépendent de la fiabilité des informations du système dans le suivi des
44 __author__ = "Jean-Philippe ARGAUD"
53 # ==============================================================================
54 class PlatformInfo(object):
56 Rassemblement des informations sur le code et la plateforme
63 "Retourne le nom de l'application"
64 import daCore.version as dav
68 "Retourne le numéro de la version"
69 import daCore.version as dav
73 "Retourne la date de création de la version"
74 import daCore.version as dav
78 "Retourne l'année de création de la version"
79 import daCore.version as dav
82 def getSystemInformation(self, __prefix=""):
84 __msg += "\n%s%30s : %s" %(__prefix,"platform.system",platform.system())
85 __msg += "\n%s%30s : %s" %(__prefix,"sys.platform",sys.platform)
86 __msg += "\n%s%30s : %s" %(__prefix,"platform.version",platform.version())
87 __msg += "\n%s%30s : %s" %(__prefix,"platform.platform",platform.platform())
88 __msg += "\n%s%30s : %s" %(__prefix,"platform.machine",platform.machine())
89 if len(platform.processor())>0:
90 __msg += "\n%s%30s : %s" %(__prefix,"platform.processor",platform.processor())
92 if sys.platform.startswith('linux'):
93 if hasattr(platform, 'linux_distribution'):
94 __msg += "\n%s%30s : %s" %(__prefix,
95 "platform.linux_distribution",str(platform.linux_distribution()))
96 elif hasattr(platform, 'dist'):
97 __msg += "\n%s%30s : %s" %(__prefix,"platform.dist",str(platform.dist()))
98 elif sys.platform.startswith('darwin'):
99 if hasattr(platform, 'mac_ver'):
100 __macosxv = {'5': 'Leopard', '6': 'Snow Leopard', '7': 'Lion',
101 '8': 'Mountain Lion', '9': 'Mavericks', '10': 'Yosemite',
102 '11': 'El Capitan', '12': 'Sierra'}
103 for key in __macosxv:
104 if (platform.mac_ver()[0].split('.')[1] == key):
105 __msg += "\n%s%30s : %s" %(__prefix,
106 "platform.mac_ver",str(platform.mac_ver()[0]+"(" + macosx_dict[key]+")"))
107 elif hasattr(platform, 'dist'):
108 __msg += "\n%s%30s : %s" %(__prefix,"platform.dist",str(platform.dist()))
109 elif os.name == 'nt':
110 __msg += "\n%s%30s : %s" %(__prefix,"platform.win32_ver",platform.win32_ver()[1])
113 __msg += "\n%s%30s : %s" %(__prefix,"platform.python_implementation",platform.python_implementation())
114 __msg += "\n%s%30s : %s" %(__prefix,"sys.executable",sys.executable)
115 __msg += "\n%s%30s : %s" %(__prefix,"sys.version",sys.version.replace('\n',''))
116 __msg += "\n%s%30s : %s" %(__prefix,"sys.getfilesystemencoding",str(sys.getfilesystemencoding()))
117 __msg += "\n%s%30s : %s" %(__prefix,"locale.getdefaultlocale",str(locale.getdefaultlocale()))
119 __msg += "\n%s%30s : %s" %(__prefix,"os.cpu_count",os.cpu_count())
120 if hasattr(os, 'sched_getaffinity'):
121 __msg += "\n%s%30s : %s" %(__prefix,"len(os.sched_getaffinity(0))",len(os.sched_getaffinity(0)))
123 __msg += "\n%s%30s : %s" %(__prefix,"len(os.sched_getaffinity(0))","Unsupported on this platform")
125 __msg += "\n%s%30s : %s" %(__prefix,"platform.node",platform.node())
126 __msg += "\n%s%30s : %s" %(__prefix,"os.path.expanduser",os.path.expanduser('~'))
129 def getPythonVersion(self):
130 "Retourne la version de python disponible"
131 return ".".join([str(x) for x in sys.version_info[0:3]]) # map(str,sys.version_info[0:3]))
133 def getNumpyVersion(self):
134 "Retourne la version de numpy disponible"
136 return numpy.version.version
138 def getScipyVersion(self):
139 "Retourne la version de scipy disponible"
141 __version = scipy.version.version
146 def getMatplotlibVersion(self):
147 "Retourne la version de matplotlib disponible"
149 __version = matplotlib.__version__
154 def getGnuplotVersion(self):
155 "Retourne la version de gnuplotpy disponible"
157 __version = Gnuplot.__version__
162 def getSphinxVersion(self):
163 "Retourne la version de sphinx disponible"
165 __version = sphinx.__version__
170 def getNloptVersion(self):
171 "Retourne la version de nlopt disponible"
173 __version = "%s.%s.%s"%(
174 nlopt.version_major(),
175 nlopt.version_minor(),
176 nlopt.version_bugfix(),
182 def getCurrentMemorySize(self):
183 "Retourne la taille mémoire courante utilisée"
186 def MaximumPrecision(self):
187 "Retourne la precision maximale flottante pour Numpy"
190 numpy.array([1.,], dtype='float128')
196 def MachinePrecision(self):
197 # Alternative sans module :
201 # eps = (1.0 + eps/2) - 1.0
202 return sys.float_info.epsilon
205 import daCore.version as dav
206 return "%s %s (%s)"%(dav.name,dav.version,dav.date)
208 # ==============================================================================
212 import scipy.optimize
219 has_matplotlib = True
221 has_matplotlib = False
247 has_salome = bool( "ROOT_SALOME" in os.environ )
248 has_yacs = bool( "YACS_ROOT_DIR" in os.environ )
249 has_adao = bool( "ADAO_ROOT_DIR" in os.environ )
250 has_eficas = bool( "EFICAS_ROOT_DIR" in os.environ )
252 # ==============================================================================
253 def uniq( __sequence ):
255 Fonction pour rendre unique chaque élément d'une liste, en préservant l'ordre
258 return [x for x in __sequence if x not in __seen and not __seen.add(x)]
260 def isIterable( __sequence, __check = False, __header = "" ):
262 Vérification que l'argument est un itérable interne.
263 Remarque : pour permettre le test correct en MultiFonctions,
264 - Ne pas accepter comme itérable un "numpy.ndarray"
265 - Ne pas accepter comme itérable avec hasattr(__sequence, "__iter__")
267 if isinstance( __sequence, (list, tuple, map, dict) ):
269 elif type(__sequence).__name__ in ('generator','range'):
271 elif "_iterator" in type(__sequence).__name__:
275 if __check and not __isOk:
276 raise TypeError("Not iterable or unkown input type%s: %s"%(__header, type(__sequence),))
279 def date2int( __date, __lang="FR" ):
281 Fonction de secours, conversion pure : dd/mm/yy hh:mm ---> int(yyyymmddhhmm)
283 __date = __date.strip()
284 if __date.count('/') == 2 and __date.count(':') == 0 and __date.count(' ') == 0:
285 d,m,y = __date.split("/")
286 __number = (10**4)*int(y)+(10**2)*int(m)+int(d)
287 elif __date.count('/') == 2 and __date.count(':') == 1 and __date.count(' ') > 0:
288 part1, part2 = __date.split()
289 d,m,y = part1.strip().split("/")
290 h,n = part2.strip().split(":")
291 __number = (10**8)*int(y)+(10**6)*int(m)+(10**4)*int(d)+(10**2)*int(h)+int(n)
293 raise ValueError("Cannot convert \"%s\" as a D/M/Y H:M date"%d)
296 def checkFileNameConformity( __filename, __warnInsteadOfPrint=True ):
297 if sys.platform.startswith("win") and len(__filename) > 256:
299 __msg = (" For some shared or older file systems on Windows, a file "+\
300 "name longer than 256 characters can lead to access problems."+\
301 "\n The name of the file in question is the following:"+\
302 "\n %s")%(__filename,)
303 if __warnInsteadOfPrint: logging.warning(__msg)
310 def checkFileNameImportability( __filename, __warnInsteadOfPrint=True ):
311 if str(__filename).count(".") > 1:
313 __msg = (" The file name contains %i point(s) before the extension "+\
314 "separator, which can potentially lead to problems when "+\
315 "importing this file into Python, as it can then be recognized "+\
316 "as a sub-module (generating a \"ModuleNotFoundError\"). If it "+\
317 "is intentional, make sure that there is no module with the "+\
318 "same name as the part before the first point, and that there is "+\
319 "no \"__init__.py\" file in the same directory."+\
320 "\n The name of the file in question is the following:"+\
321 "\n %s")%(int(str(__filename).count(".")-1), __filename)
322 if __warnInsteadOfPrint is None: pass
323 elif __warnInsteadOfPrint: logging.warning(__msg)
330 # ==============================================================================
331 class PathManagement(object):
333 Mise à jour du path système pour les répertoires d'outils
336 "Déclaration des répertoires statiques"
337 parent = os.path.abspath(os.path.join(os.path.dirname(__file__),".."))
339 self.__paths["daNumerics"] = os.path.join(parent,"daNumerics")
341 for v in self.__paths.values():
342 sys.path.insert(0, v )
344 # Conserve en unique exemplaire chaque chemin
345 sys.path = uniq( sys.path )
350 Renvoie le dictionnaire des chemins ajoutés
354 # ==============================================================================
355 class SystemUsage(object):
357 Permet de récupérer les différentes tailles mémoires du process courant
360 # Le module resource renvoie 0 pour les tailles mémoire. On utilise donc
361 # plutôt : http://code.activestate.com/recipes/286222/ et Wikipedia
363 _proc_status = '/proc/%d/status' % os.getpid()
364 _memo_status = '/proc/meminfo'
366 'o' : 1.0, # Multiples SI de l'octet
370 'kio': 1024.0, # Multiples binaires de l'octet
371 'Mio': 1024.0*1024.0,
372 'Gio': 1024.0*1024.0*1024.0,
373 'B': 1.0, # Multiples binaires du byte=octet
375 'MB' : 1024.0*1024.0,
376 'GB' : 1024.0*1024.0*1024.0,
383 def _VmA(self, VmKey, unit):
384 "Lecture des paramètres mémoire de la machine"
386 t = open(self._memo_status)
390 return 0.0 # non-Linux?
391 i = v.index(VmKey) # get VmKey line e.g. 'VmRSS: 9999 kB\n ...'
392 v = v[i:].split(None, 3) # whitespace
394 return 0.0 # invalid format?
395 # convert Vm value to bytes
396 mem = float(v[1]) * self._scale[v[2]]
397 return mem / self._scale[unit]
399 def getAvailablePhysicalMemory(self, unit="o"):
400 "Renvoie la mémoire physique utilisable en octets"
401 return self._VmA('MemTotal:', unit)
403 def getAvailableSwapMemory(self, unit="o"):
404 "Renvoie la mémoire swap utilisable en octets"
405 return self._VmA('SwapTotal:', unit)
407 def getAvailableMemory(self, unit="o"):
408 "Renvoie la mémoire totale (physique+swap) utilisable en octets"
409 return self._VmA('MemTotal:', unit) + self._VmA('SwapTotal:', unit)
411 def getUsableMemory(self, unit="o"):
412 """Renvoie la mémoire utilisable en octets
413 Rq : il n'est pas sûr que ce décompte soit juste...
415 return self._VmA('MemFree:', unit) + self._VmA('SwapFree:', unit) + \
416 self._VmA('Cached:', unit) + self._VmA('SwapCached:', unit)
418 def _VmB(self, VmKey, unit):
419 "Lecture des paramètres mémoire du processus"
421 t = open(self._proc_status)
425 return 0.0 # non-Linux?
426 i = v.index(VmKey) # get VmKey line e.g. 'VmRSS: 9999 kB\n ...'
427 v = v[i:].split(None, 3) # whitespace
429 return 0.0 # invalid format?
430 # convert Vm value to bytes
431 mem = float(v[1]) * self._scale[v[2]]
432 return mem / self._scale[unit]
434 def getUsedMemory(self, unit="o"):
435 "Renvoie la mémoire résidente utilisée en octets"
436 return self._VmB('VmRSS:', unit)
438 def getVirtualMemory(self, unit="o"):
439 "Renvoie la mémoire totale utilisée en octets"
440 return self._VmB('VmSize:', unit)
442 def getUsedStacksize(self, unit="o"):
443 "Renvoie la taille du stack utilisé en octets"
444 return self._VmB('VmStk:', unit)
446 def getMaxUsedMemory(self, unit="o"):
447 "Renvoie la mémoire résidente maximale mesurée"
448 return self._VmB('VmHWM:', unit)
450 def getMaxVirtualMemory(self, unit="o"):
451 "Renvoie la mémoire totale maximale mesurée"
452 return self._VmB('VmPeak:', unit)
454 # ==============================================================================
455 if __name__ == "__main__":
456 print('\n AUTODIAGNOSTIC\n')