Salome HOME
2d474c7a52051cfc93f357955a9fb0897eb5faf3
[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 date2int(__date, __lang="FR"):
254     """
255     Fonction de secours, conversion pure : dd/mm/yy hh:mm ---> int(yyyymmddhhmm)
256     """
257     __date = __date.strip()
258     if __date.count('/') == 2 and __date.count(':') == 0 and __date.count(' ') == 0:
259         d,m,y = __date.split("/")
260         __number = (10**4)*int(y)+(10**2)*int(m)+int(d)
261     elif __date.count('/') == 2 and __date.count(':') == 1 and __date.count(' ') > 0:
262         part1, part2 = __date.split()
263         d,m,y = part1.strip().split("/")
264         h,n   = part2.strip().split(":")
265         __number = (10**8)*int(y)+(10**6)*int(m)+(10**4)*int(d)+(10**2)*int(h)+int(n)
266     else:
267         raise ValueError("Cannot convert \"%s\" as a D/M/Y H:M date"%d)
268     return __number
269
270 # ==============================================================================
271 class PathManagement(object):
272     """
273     Mise à jour du path système pour les répertoires d'outils
274     """
275     def __init__(self):
276         "Déclaration des répertoires statiques"
277         parent = os.path.abspath(os.path.join(os.path.dirname(__file__),".."))
278         self.__paths = {}
279         self.__paths["daNumerics"]  = os.path.join(parent,"daNumerics")
280         #
281         for v in self.__paths.values():
282             sys.path.insert(0, v )
283         #
284         # Conserve en unique exemplaire chaque chemin
285         sys.path = uniq( sys.path )
286         del parent
287
288     def getpaths(self):
289         """
290         Renvoie le dictionnaire des chemins ajoutés
291         """
292         return self.__paths
293
294 # ==============================================================================
295 class SystemUsage(object):
296     """
297     Permet de récupérer les différentes tailles mémoires du process courant
298     """
299     #
300     # Le module resource renvoie 0 pour les tailles mémoire. On utilise donc
301     # plutôt : http://code.activestate.com/recipes/286222/ et Wikipedia
302     #
303     _proc_status = '/proc/%d/status' % os.getpid()
304     _memo_status = '/proc/meminfo'
305     _scale = {
306         'o'  : 1.0,     # Multiples SI de l'octet
307         'ko' : 1.e3,
308         'Mo' : 1.e6,
309         'Go' : 1.e9,
310         'kio': 1024.0,  # Multiples binaires de l'octet
311         'Mio': 1024.0*1024.0,
312         'Gio': 1024.0*1024.0*1024.0,
313         'B':     1.0,   # Multiples binaires du byte=octet
314         'kB' : 1024.0,
315         'MB' : 1024.0*1024.0,
316         'GB' : 1024.0*1024.0*1024.0,
317         }
318     #
319     def __init__(self):
320         "Sans effet"
321         pass
322     #
323     def _VmA(self, VmKey, unit):
324         "Lecture des paramètres mémoire de la machine"
325         try:
326             t = open(self._memo_status)
327             v = t.read()
328             t.close()
329         except IOError:
330             return 0.0           # non-Linux?
331         i = v.index(VmKey)       # get VmKey line e.g. 'VmRSS:  9999  kB\n ...'
332         v = v[i:].split(None, 3) # whitespace
333         if len(v) < 3:
334             return 0.0           # invalid format?
335         # convert Vm value to bytes
336         mem = float(v[1]) * self._scale[v[2]]
337         return mem / self._scale[unit]
338     #
339     def getAvailablePhysicalMemory(self, unit="o"):
340         "Renvoie la mémoire physique utilisable en octets"
341         return self._VmA('MemTotal:', unit)
342     #
343     def getAvailableSwapMemory(self, unit="o"):
344         "Renvoie la mémoire swap utilisable en octets"
345         return self._VmA('SwapTotal:', unit)
346     #
347     def getAvailableMemory(self, unit="o"):
348         "Renvoie la mémoire totale (physique+swap) utilisable en octets"
349         return self._VmA('MemTotal:', unit) + self._VmA('SwapTotal:', unit)
350     #
351     def getUsableMemory(self, unit="o"):
352         """Renvoie la mémoire utilisable en octets
353         Rq : il n'est pas sûr que ce décompte soit juste...
354         """
355         return self._VmA('MemFree:', unit) + self._VmA('SwapFree:', unit) + \
356                self._VmA('Cached:', unit) + self._VmA('SwapCached:', unit)
357     #
358     def _VmB(self, VmKey, unit):
359         "Lecture des paramètres mémoire du processus"
360         try:
361             t = open(self._proc_status)
362             v = t.read()
363             t.close()
364         except IOError:
365             return 0.0           # non-Linux?
366         i = v.index(VmKey)       # get VmKey line e.g. 'VmRSS:  9999  kB\n ...'
367         v = v[i:].split(None, 3) # whitespace
368         if len(v) < 3:
369             return 0.0           # invalid format?
370         # convert Vm value to bytes
371         mem = float(v[1]) * self._scale[v[2]]
372         return mem / self._scale[unit]
373     #
374     def getUsedMemory(self, unit="o"):
375         "Renvoie la mémoire résidente utilisée en octets"
376         return self._VmB('VmRSS:', unit)
377     #
378     def getVirtualMemory(self, unit="o"):
379         "Renvoie la mémoire totale utilisée en octets"
380         return self._VmB('VmSize:', unit)
381     #
382     def getUsedStacksize(self, unit="o"):
383         "Renvoie la taille du stack utilisé en octets"
384         return self._VmB('VmStk:', unit)
385     #
386     def getMaxUsedMemory(self, unit="o"):
387         "Renvoie la mémoire résidente maximale mesurée"
388         return self._VmB('VmHWM:', unit)
389     #
390     def getMaxVirtualMemory(self, unit="o"):
391         "Renvoie la mémoire totale maximale mesurée"
392         return self._VmB('VmPeak:', unit)
393
394 # ==============================================================================
395 if __name__ == "__main__":
396     print('\n AUTODIAGNOSTIC \n')