Salome HOME
e46bbb41e95ce64bb10c76262d2360acb0b74a45
[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
50 # ==============================================================================
51 class PlatformInfo(object):
52     """
53     Rassemblement des informations sur le code et la plateforme
54     """
55     def __init__(self):
56         "Sans effet"
57         pass
58
59     def getName(self):
60         "Retourne le nom de l'application"
61         import daCore.version as dav
62         return dav.name
63
64     def getVersion(self):
65         "Retourne le numéro de la version"
66         import daCore.version as dav
67         return dav.version
68
69     def getDate(self):
70         "Retourne la date de création de la version"
71         import daCore.version as dav
72         return dav.date
73
74     def getYear(self):
75         "Retourne l'année de création de la version"
76         import daCore.version as dav
77         return dav.year
78
79     def getPythonVersion(self):
80         "Retourne la version de python disponible"
81         return ".".join([str(x) for x in sys.version_info[0:3]]) # map(str,sys.version_info[0:3]))
82
83     def getNumpyVersion(self):
84         "Retourne la version de numpy disponible"
85         import numpy.version
86         return numpy.version.version
87
88     def getScipyVersion(self):
89         "Retourne la version de scipy disponible"
90         if has_scipy:
91             __version = scipy.version.version
92         else:
93             __version = "0.0.0"
94         return __version
95
96     def getMatplotlibVersion(self):
97         "Retourne la version de matplotlib disponible"
98         if has_matplotlib:
99             __version = matplotlib.__version__
100         else:
101             __version = "0.0.0"
102         return __version
103
104     def getGnuplotVersion(self):
105         "Retourne la version de gnuplotpy disponible"
106         if has_gnuplot:
107             __version = Gnuplot.__version__
108         else:
109             __version = "0.0"
110         return __version
111
112     def getSphinxVersion(self):
113         "Retourne la version de sphinx disponible"
114         if has_sphinx:
115             __version = sphinx.__version__
116         else:
117             __version = "0.0.0"
118         return __version
119
120     def getNloptVersion(self):
121         "Retourne la version de nlopt disponible"
122         if has_nlopt:
123             __version = "%s.%s.%s"%(
124                 nlopt.version_major(),
125                 nlopt.version_minor(),
126                 nlopt.version_bugfix(),
127                 )
128         else:
129             __version = "0.0.0"
130         return __version
131
132     def getCurrentMemorySize(self):
133         "Retourne la taille mémoire courante utilisée"
134         return 1
135
136     def MaximumPrecision(self):
137         "Retourne la precision maximale flottante pour Numpy"
138         import numpy
139         try:
140             numpy.array([1.,], dtype='float128')
141             mfp = 'float128'
142         except Exception:
143             mfp = 'float64'
144         return mfp
145
146     def MachinePrecision(self):
147         # Alternative sans module :
148         # eps = 2.38
149         # while eps > 0:
150         #     old_eps = eps
151         #     eps = (1.0 + eps/2) - 1.0
152         return sys.float_info.epsilon
153
154     def __str__(self):
155         import daCore.version as dav
156         return "%s %s (%s)"%(dav.name,dav.version,dav.date)
157
158 # ==============================================================================
159 try:
160     import scipy
161     import scipy.version
162     import scipy.optimize
163     has_scipy = True
164 except ImportError:
165     has_scipy = False
166
167 try:
168     import matplotlib
169     has_matplotlib = True
170 except ImportError:
171     has_matplotlib = False
172
173 try:
174     import Gnuplot
175     has_gnuplot = True
176 except ImportError:
177     has_gnuplot = False
178
179 try:
180     import sphinx
181     has_sphinx = True
182 except ImportError:
183     has_sphinx = False
184
185 try:
186     import nlopt
187     has_nlopt = True
188 except ImportError:
189     has_nlopt = False
190
191 has_salome = bool( "ROOT_SALOME"   in os.environ )
192 has_yacs   = bool( "YACS_ROOT_DIR" in os.environ )
193 has_adao   = bool( "ADAO_ROOT_DIR" in os.environ )
194 has_eficas = bool( "EFICAS_ROOT_DIR" in os.environ )
195
196 # ==============================================================================
197 def uniq(__sequence):
198     """
199     Fonction pour rendre unique chaque élément d'une liste, en préservant l'ordre
200     """
201     __seen = set()
202     return [x for x in __sequence if x not in __seen and not __seen.add(x)]
203
204 def date2int(__date, __lang="FR"):
205     """
206     Fonction de secours, conversion pure : dd/mm/yy hh:mm ---> int(yyyymmddhhmm)
207     """
208     __date = __date.strip()
209     if __date.count('/') == 2 and __date.count(':') == 0 and __date.count(' ') == 0:
210         d,m,y = __date.split("/")
211         __number = (10**4)*int(y)+(10**2)*int(m)+int(d)
212     elif __date.count('/') == 2 and __date.count(':') == 1 and __date.count(' ') > 0:
213         part1, part2 = __date.split()
214         d,m,y = part1.strip().split("/")
215         h,n   = part2.strip().split(":")
216         __number = (10**8)*int(y)+(10**6)*int(m)+(10**4)*int(d)+(10**2)*int(h)+int(n)
217     else:
218         raise ValueError("Cannot convert \"%s\" as a D/M/Y H:M date"%d)
219     return __number
220
221 # ==============================================================================
222 class PathManagement(object):
223     """
224     Mise à jour du path système pour les répertoires d'outils
225     """
226     def __init__(self):
227         "Déclaration des répertoires statiques"
228         parent = os.path.abspath(os.path.join(os.path.dirname(__file__),".."))
229         self.__paths = {}
230         self.__paths["daNumerics"]  = os.path.join(parent,"daNumerics")
231         #
232         for v in self.__paths.values():
233             sys.path.insert(0, v )
234         #
235         # Conserve en unique exemplaire chaque chemin
236         sys.path = uniq( sys.path )
237         del parent
238
239     def getpaths(self):
240         """
241         Renvoie le dictionnaire des chemins ajoutés
242         """
243         return self.__paths
244
245 # ==============================================================================
246 class SystemUsage(object):
247     """
248     Permet de récupérer les différentes tailles mémoires du process courant
249     """
250     #
251     # Le module resource renvoie 0 pour les tailles mémoire. On utilise donc
252     # plutôt : http://code.activestate.com/recipes/286222/ et Wikipedia
253     #
254     _proc_status = '/proc/%d/status' % os.getpid()
255     _memo_status = '/proc/meminfo'
256     _scale = {
257         'o'  : 1.0,     # Multiples SI de l'octet
258         'ko' : 1.e3,
259         'Mo' : 1.e6,
260         'Go' : 1.e9,
261         'kio': 1024.0,  # Multiples binaires de l'octet
262         'Mio': 1024.0*1024.0,
263         'Gio': 1024.0*1024.0*1024.0,
264         'B':     1.0,   # Multiples binaires du byte=octet
265         'kB' : 1024.0,
266         'MB' : 1024.0*1024.0,
267         'GB' : 1024.0*1024.0*1024.0,
268         }
269     #
270     def __init__(self):
271         "Sans effet"
272         pass
273     #
274     def _VmA(self, VmKey, unit):
275         "Lecture des paramètres mémoire de la machine"
276         try:
277             t = open(self._memo_status)
278             v = t.read()
279             t.close()
280         except IOError:
281             return 0.0           # non-Linux?
282         i = v.index(VmKey)       # get VmKey line e.g. 'VmRSS:  9999  kB\n ...'
283         v = v[i:].split(None, 3) # whitespace
284         if len(v) < 3:
285             return 0.0           # invalid format?
286         # convert Vm value to bytes
287         mem = float(v[1]) * self._scale[v[2]]
288         return mem / self._scale[unit]
289     #
290     def getAvailablePhysicalMemory(self, unit="o"):
291         "Renvoie la mémoire physique utilisable en octets"
292         return self._VmA('MemTotal:', unit)
293     #
294     def getAvailableSwapMemory(self, unit="o"):
295         "Renvoie la mémoire swap utilisable en octets"
296         return self._VmA('SwapTotal:', unit)
297     #
298     def getAvailableMemory(self, unit="o"):
299         "Renvoie la mémoire totale (physique+swap) utilisable en octets"
300         return self._VmA('MemTotal:', unit) + self._VmA('SwapTotal:', unit)
301     #
302     def getUsableMemory(self, unit="o"):
303         """Renvoie la mémoire utilisable en octets
304         Rq : il n'est pas sûr que ce décompte soit juste...
305         """
306         return self._VmA('MemFree:', unit) + self._VmA('SwapFree:', unit) + \
307                self._VmA('Cached:', unit) + self._VmA('SwapCached:', unit)
308     #
309     def _VmB(self, VmKey, unit):
310         "Lecture des paramètres mémoire du processus"
311         try:
312             t = open(self._proc_status)
313             v = t.read()
314             t.close()
315         except IOError:
316             return 0.0           # non-Linux?
317         i = v.index(VmKey)       # get VmKey line e.g. 'VmRSS:  9999  kB\n ...'
318         v = v[i:].split(None, 3) # whitespace
319         if len(v) < 3:
320             return 0.0           # invalid format?
321         # convert Vm value to bytes
322         mem = float(v[1]) * self._scale[v[2]]
323         return mem / self._scale[unit]
324     #
325     def getUsedMemory(self, unit="o"):
326         "Renvoie la mémoire résidente utilisée en octets"
327         return self._VmB('VmRSS:', unit)
328     #
329     def getVirtualMemory(self, unit="o"):
330         "Renvoie la mémoire totale utilisée en octets"
331         return self._VmB('VmSize:', unit)
332     #
333     def getUsedStacksize(self, unit="o"):
334         "Renvoie la taille du stack utilisé en octets"
335         return self._VmB('VmStk:', unit)
336     #
337     def getMaxUsedMemory(self, unit="o"):
338         "Renvoie la mémoire résidente maximale mesurée"
339         return self._VmB('VmHWM:', unit)
340     #
341     def getMaxVirtualMemory(self, unit="o"):
342         "Renvoie la mémoire totale maximale mesurée"
343         return self._VmB('VmPeak:', unit)
344
345 # ==============================================================================
346 if __name__ == "__main__":
347     print('\n AUTODIAGNOSTIC \n')