Salome HOME
Adding multi-functions input capabilities (1)
[modules/adao.git] / src / daComposant / daCore / PlatformInfo.py
1 # -*- coding: utf-8 -*-
2 #
3 # Copyright (C) 2008-2018 EDF R&D
4 #
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.
9 #
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.
14 #
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
18 #
19 # See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
20 #
21 # Author: Jean-Philippe Argaud, jean-philippe.argaud@edf.fr, EDF R&D
22
23 """
24     Informations sur le code et la plateforme, et mise à jour des chemins
25
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 :
30         print(PlatformInfo())
31         print(PlatformInfo().getVersion())
32         created = PlatformInfo().getDate()
33
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 :
37         PathManagement()
38
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
42     process.
43 """
44 __author__ = "Jean-Philippe ARGAUD"
45 __all__ = []
46
47 import os
48 import sys
49 import platform
50 import locale
51
52 # ==============================================================================
53 class PlatformInfo(object):
54     """
55     Rassemblement des informations sur le code et la plateforme
56     """
57     def __init__(self):
58         "Sans effet"
59         pass
60
61     def getName(self):
62         "Retourne le nom de l'application"
63         import daCore.version as dav
64         return dav.name
65
66     def getVersion(self):
67         "Retourne le numéro de la version"
68         import daCore.version as dav
69         return dav.version
70
71     def getDate(self):
72         "Retourne la date de création de la version"
73         import daCore.version as dav
74         return dav.date
75
76     def getYear(self):
77         "Retourne l'année de création de la version"
78         import daCore.version as dav
79         return dav.year
80
81     def getSystemInformation(self, __prefix=""):
82         __msg  = ""
83         __msg += "\n%s%30s : %s" %(__prefix,"platform.system",platform.system())
84         __msg += "\n%s%30s : %s" %(__prefix,"sys.platform",sys.platform)
85         __msg += "\n%s%30s : %s" %(__prefix,"platform.version",platform.version())
86         __msg += "\n%s%30s : %s" %(__prefix,"platform.platform",platform.platform())
87         __msg += "\n%s%30s : %s" %(__prefix,"platform.machine",platform.machine())
88         if len(platform.processor())>0:
89             __msg += "\n%s%30s : %s" %(__prefix,"platform.processor",platform.processor())
90         #
91         if sys.platform.startswith('linux'):
92             if hasattr(platform, 'linux_distribution'):
93                 __msg += "\n%s%30s : %s" %(__prefix,
94                     "platform.linux_distribution",str(platform.linux_distribution()))
95             else:
96                 __msg += "\n%s%30s : %s" %(__prefix,"platform.dist",str(platform.dist()))
97         elif sys.platform.startswith('darwin'):
98             if hasattr(platform, 'mac_ver'):
99                 __macosxv = {'5': 'Leopard',       '6': 'Snow Leopard', '7': 'Lion',
100                              '8': 'Mountain Lion', '9': 'Mavericks',   '10': 'Yosemite',
101                              '11': 'El Capitan',  '12': 'Sierra'}
102                 for key in __macosxv:
103                     if (platform.mac_ver()[0].split('.')[1] == key):
104                         __msg += "\n%s%30s : %s" %(__prefix,
105                             "platform.mac_ver",str(platform.mac_ver()[0]+"(" + macosx_dict[key]+")"))
106             else:
107                 __msg += "\n%s%30s : %s" %(__prefix,"platform.dist",str(platform.dist()))
108         elif os.name == 'nt':
109             __msg += "\n%s%30s : %s" %(__prefix,"platform.win32_ver",platform.win32_ver()[1])
110         #
111         __msg += "\n"
112         __msg += "\n%s%30s : %s" %(__prefix,"platform.python_implementation",platform.python_implementation())
113         __msg += "\n%s%30s : %s" %(__prefix,"sys.executable",sys.executable)
114         __msg += "\n%s%30s : %s" %(__prefix,"sys.version",sys.version.replace('\n',''))
115         __msg += "\n%s%30s : %s" %(__prefix,"sys.getfilesystemencoding",str(sys.getfilesystemencoding()))
116         __msg += "\n%s%30s : %s" %(__prefix,"locale.getdefaultlocale",str(locale.getdefaultlocale()))
117         __msg += "\n"
118         __msg += "\n%s%30s : %s" %(__prefix,"platform.node",platform.node())
119         __msg += "\n%s%30s : %s" %(__prefix,"os.path.expanduser",os.path.expanduser('~'))
120         return __msg
121
122     def getPythonVersion(self):
123         "Retourne la version de python disponible"
124         return ".".join([str(x) for x in sys.version_info[0:3]]) # map(str,sys.version_info[0:3]))
125
126     def getNumpyVersion(self):
127         "Retourne la version de numpy disponible"
128         import numpy.version
129         return numpy.version.version
130
131     def getScipyVersion(self):
132         "Retourne la version de scipy disponible"
133         if has_scipy:
134             __version = scipy.version.version
135         else:
136             __version = "0.0.0"
137         return __version
138
139     def getMatplotlibVersion(self):
140         "Retourne la version de matplotlib disponible"
141         if has_matplotlib:
142             __version = matplotlib.__version__
143         else:
144             __version = "0.0.0"
145         return __version
146
147     def getGnuplotVersion(self):
148         "Retourne la version de gnuplotpy disponible"
149         if has_gnuplot:
150             __version = Gnuplot.__version__
151         else:
152             __version = "0.0"
153         return __version
154
155     def getSphinxVersion(self):
156         "Retourne la version de sphinx disponible"
157         if has_sphinx:
158             __version = sphinx.__version__
159         else:
160             __version = "0.0.0"
161         return __version
162
163     def getNloptVersion(self):
164         "Retourne la version de nlopt disponible"
165         if has_nlopt:
166             __version = "%s.%s.%s"%(
167                 nlopt.version_major(),
168                 nlopt.version_minor(),
169                 nlopt.version_bugfix(),
170                 )
171         else:
172             __version = "0.0.0"
173         return __version
174
175     def getCurrentMemorySize(self):
176         "Retourne la taille mémoire courante utilisée"
177         return 1
178
179     def MaximumPrecision(self):
180         "Retourne la precision maximale flottante pour Numpy"
181         import numpy
182         try:
183             numpy.array([1.,], dtype='float128')
184             mfp = 'float128'
185         except Exception:
186             mfp = 'float64'
187         return mfp
188
189     def MachinePrecision(self):
190         # Alternative sans module :
191         # eps = 2.38
192         # while eps > 0:
193         #     old_eps = eps
194         #     eps = (1.0 + eps/2) - 1.0
195         return sys.float_info.epsilon
196
197     def __str__(self):
198         import daCore.version as dav
199         return "%s %s (%s)"%(dav.name,dav.version,dav.date)
200
201 # ==============================================================================
202 try:
203     import scipy
204     import scipy.version
205     import scipy.optimize
206     has_scipy = True
207 except ImportError:
208     has_scipy = False
209
210 try:
211     import matplotlib
212     has_matplotlib = True
213 except ImportError:
214     has_matplotlib = False
215
216 try:
217     import Gnuplot
218     has_gnuplot = True
219 except ImportError:
220     has_gnuplot = False
221
222 try:
223     import sphinx
224     has_sphinx = True
225 except ImportError:
226     has_sphinx = False
227
228 try:
229     import nlopt
230     has_nlopt = True
231 except ImportError:
232     has_nlopt = False
233
234 try:
235     import sdf
236     has_sdf = True
237 except ImportError:
238     has_sdf = False
239
240 has_salome = bool( "ROOT_SALOME"   in os.environ )
241 has_yacs   = bool( "YACS_ROOT_DIR" in os.environ )
242 has_adao   = bool( "ADAO_ROOT_DIR" in os.environ )
243 has_eficas = bool( "EFICAS_ROOT_DIR" in os.environ )
244
245 # ==============================================================================
246 def uniq( __sequence ):
247     """
248     Fonction pour rendre unique chaque élément d'une liste, en préservant l'ordre
249     """
250     __seen = set()
251     return [x for x in __sequence if x not in __seen and not __seen.add(x)]
252
253 def isIterable( __sequence, __check = False, __header = "" ):
254     """
255     Vérification que l'argument est un itérable
256     """
257     if  isinstance( __sequence, (list, tuple, map) ):
258         __isOk = True
259     elif type(__sequence).__name__ in ('generator','range'):
260         __isOk = True
261     elif "_iterator" in type(__sequence).__name__:
262         __isOk = True
263     else:
264         __isOk = False
265     if __check and not __isOk:
266         raise TypeError("Not iterable or unkown input type%s: %s"%(__header, type(__sequence),))
267     return __isOk
268
269 def date2int( __date, __lang="FR" ):
270     """
271     Fonction de secours, conversion pure : dd/mm/yy hh:mm ---> int(yyyymmddhhmm)
272     """
273     __date = __date.strip()
274     if __date.count('/') == 2 and __date.count(':') == 0 and __date.count(' ') == 0:
275         d,m,y = __date.split("/")
276         __number = (10**4)*int(y)+(10**2)*int(m)+int(d)
277     elif __date.count('/') == 2 and __date.count(':') == 1 and __date.count(' ') > 0:
278         part1, part2 = __date.split()
279         d,m,y = part1.strip().split("/")
280         h,n   = part2.strip().split(":")
281         __number = (10**8)*int(y)+(10**6)*int(m)+(10**4)*int(d)+(10**2)*int(h)+int(n)
282     else:
283         raise ValueError("Cannot convert \"%s\" as a D/M/Y H:M date"%d)
284     return __number
285
286 # ==============================================================================
287 class PathManagement(object):
288     """
289     Mise à jour du path système pour les répertoires d'outils
290     """
291     def __init__(self):
292         "Déclaration des répertoires statiques"
293         parent = os.path.abspath(os.path.join(os.path.dirname(__file__),".."))
294         self.__paths = {}
295         self.__paths["daNumerics"]  = os.path.join(parent,"daNumerics")
296         #
297         for v in self.__paths.values():
298             sys.path.insert(0, v )
299         #
300         # Conserve en unique exemplaire chaque chemin
301         sys.path = uniq( sys.path )
302         del parent
303
304     def getpaths(self):
305         """
306         Renvoie le dictionnaire des chemins ajoutés
307         """
308         return self.__paths
309
310 # ==============================================================================
311 class SystemUsage(object):
312     """
313     Permet de récupérer les différentes tailles mémoires du process courant
314     """
315     #
316     # Le module resource renvoie 0 pour les tailles mémoire. On utilise donc
317     # plutôt : http://code.activestate.com/recipes/286222/ et Wikipedia
318     #
319     _proc_status = '/proc/%d/status' % os.getpid()
320     _memo_status = '/proc/meminfo'
321     _scale = {
322         'o'  : 1.0,     # Multiples SI de l'octet
323         'ko' : 1.e3,
324         'Mo' : 1.e6,
325         'Go' : 1.e9,
326         'kio': 1024.0,  # Multiples binaires de l'octet
327         'Mio': 1024.0*1024.0,
328         'Gio': 1024.0*1024.0*1024.0,
329         'B':     1.0,   # Multiples binaires du byte=octet
330         'kB' : 1024.0,
331         'MB' : 1024.0*1024.0,
332         'GB' : 1024.0*1024.0*1024.0,
333         }
334     #
335     def __init__(self):
336         "Sans effet"
337         pass
338     #
339     def _VmA(self, VmKey, unit):
340         "Lecture des paramètres mémoire de la machine"
341         try:
342             t = open(self._memo_status)
343             v = t.read()
344             t.close()
345         except IOError:
346             return 0.0           # non-Linux?
347         i = v.index(VmKey)       # get VmKey line e.g. 'VmRSS:  9999  kB\n ...'
348         v = v[i:].split(None, 3) # whitespace
349         if len(v) < 3:
350             return 0.0           # invalid format?
351         # convert Vm value to bytes
352         mem = float(v[1]) * self._scale[v[2]]
353         return mem / self._scale[unit]
354     #
355     def getAvailablePhysicalMemory(self, unit="o"):
356         "Renvoie la mémoire physique utilisable en octets"
357         return self._VmA('MemTotal:', unit)
358     #
359     def getAvailableSwapMemory(self, unit="o"):
360         "Renvoie la mémoire swap utilisable en octets"
361         return self._VmA('SwapTotal:', unit)
362     #
363     def getAvailableMemory(self, unit="o"):
364         "Renvoie la mémoire totale (physique+swap) utilisable en octets"
365         return self._VmA('MemTotal:', unit) + self._VmA('SwapTotal:', unit)
366     #
367     def getUsableMemory(self, unit="o"):
368         """Renvoie la mémoire utilisable en octets
369         Rq : il n'est pas sûr que ce décompte soit juste...
370         """
371         return self._VmA('MemFree:', unit) + self._VmA('SwapFree:', unit) + \
372                self._VmA('Cached:', unit) + self._VmA('SwapCached:', unit)
373     #
374     def _VmB(self, VmKey, unit):
375         "Lecture des paramètres mémoire du processus"
376         try:
377             t = open(self._proc_status)
378             v = t.read()
379             t.close()
380         except IOError:
381             return 0.0           # non-Linux?
382         i = v.index(VmKey)       # get VmKey line e.g. 'VmRSS:  9999  kB\n ...'
383         v = v[i:].split(None, 3) # whitespace
384         if len(v) < 3:
385             return 0.0           # invalid format?
386         # convert Vm value to bytes
387         mem = float(v[1]) * self._scale[v[2]]
388         return mem / self._scale[unit]
389     #
390     def getUsedMemory(self, unit="o"):
391         "Renvoie la mémoire résidente utilisée en octets"
392         return self._VmB('VmRSS:', unit)
393     #
394     def getVirtualMemory(self, unit="o"):
395         "Renvoie la mémoire totale utilisée en octets"
396         return self._VmB('VmSize:', unit)
397     #
398     def getUsedStacksize(self, unit="o"):
399         "Renvoie la taille du stack utilisé en octets"
400         return self._VmB('VmStk:', unit)
401     #
402     def getMaxUsedMemory(self, unit="o"):
403         "Renvoie la mémoire résidente maximale mesurée"
404         return self._VmB('VmHWM:', unit)
405     #
406     def getMaxVirtualMemory(self, unit="o"):
407         "Renvoie la mémoire totale maximale mesurée"
408         return self._VmB('VmPeak:', unit)
409
410 # ==============================================================================
411 if __name__ == "__main__":
412     print('\n AUTODIAGNOSTIC \n')