1 #-*-coding:iso-8859-1-*-
3 # Copyright (C) 2008-2013 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 Définit des outils de persistence et d'enregistrement de séries de valeurs
25 pour analyse ultérieure ou utilisation de calcul.
27 __author__ = "Jean-Philippe ARGAUD"
31 from PlatformInfo import PathManagement ; PathManagement()
33 # ==============================================================================
36 Classe générale de persistence définissant les accesseurs nécessaires
39 def __init__(self, name="", unit="", basetype=str):
43 basetype : type de base de l'objet stocké à chaque pas
45 La gestion interne des données est exclusivement basée sur les variables
46 initialisées ici (qui ne sont pas accessibles depuis l'extérieur des
47 objets comme des attributs) :
48 __step : numérotation par défaut du pas courant
49 __basetype : le type de base de chaque valeur, sous la forme d'un type
50 permettant l'instanciation ou le casting Python
51 __steps : les pas de stockage. Par défaut, c'est __step
52 __values : les valeurs de stockage. Par défaut, c'est None
54 self.__name = str(name)
55 self.__unit = str(unit)
58 self.__basetype = basetype
65 self.__dynamic = False
67 self.__dataobservers = []
69 def basetype(self, basetype=None):
71 Renvoie ou met en place le type de base des objets stockés
74 return self.__basetype
76 self.__basetype = basetype
78 def store(self, value=None, step=None, tags={}):
80 Stocke une valeur à un pas. Une instanciation est faite avec le type de
81 base pour stocker l'objet. Si le pas n'est pas fournit, on utilise
82 l'étape de stockage comme valeur de pas.
84 if value is None: raise ValueError("Value argument required")
87 self.__steps.append(step)
89 self.__steps.append(self.__step)
91 self.__values.append(self.__basetype(value))
93 self.__tags.append( dict(tags))
94 self.__tagkeys.update(dict(tags))
96 if self.__dynamic: self.__replots()
97 for hook, parameters, scheduler in self.__dataobservers:
98 if self.__step in scheduler:
99 hook( self, parameters )
101 def pop(self, item=None, step=None):
103 Retire une valeur enregistree. Par defaut, retire par le numero d'item,
104 sinon cherche le step demande et le retire s'il existe. Sans argument,
105 retire le dernier objet enregistre.
106 Attention, la liste des cles "tagkeys" n'est pas mise a jour.
110 self.__steps.pop(index)
111 self.__values.pop(index)
112 self.__tags.pop(index)
113 elif step is not None:
114 index = int(self.__steps.index(int(step)))
115 self.__steps.pop(index)
116 self.__values.pop(index)
117 self.__tags.pop(index)
125 Renvoie la taille sous forme numpy du dernier objet stocké. Si c'est un
126 objet numpy, renvoie le shape. Si c'est un entier, un flottant, un
127 complexe, renvoie 1. Si c'est une liste ou un dictionnaire, renvoie la
128 longueur. Par défaut, renvoie 1.
130 if len(self.__values) > 0:
131 if self.__basetype in [numpy.matrix, numpy.array]:
132 return self.__values[-1].shape
133 elif self.__basetype in [int, float]:
135 elif self.__basetype in [list, dict]:
136 return (len(self.__values[-1]),)
140 raise ValueError("Object has no shape before its first storage")
144 Renvoie le nombre d'éléments dans un séquence ou la plus grande
145 dimension d'une matrice
147 return max( self.shape() )
149 # ---------------------------------------------------------
150 def itemserie(self, item=None, step=None, tags=None,
153 Les "item" sont les index de la liste des pas de "step". Ils sont
154 renvoyés par cette fonction selon les filtres définis par les mots-clés.
156 Les comportements sont les suivants :
157 - Renvoie par défaut toute la liste des index.
158 - Si l'argument "item" est valide, renvoie uniquement cet index.
159 - Si l'argument "step" existe dans la liste des pas de stockage,
160 renvoie le premier index (si allSteps=False) ou tous les index
161 (si allSteps=True) de ce "step" dans les pas de stockage.
162 - Si l'argument "tags" est un dictionnaire correct, renvoie les
163 index des pas caractérisés par toutes les paires "tag/valeur" des
164 tags indiqués, ou rien sinon.
166 Cette méthode est à vocation interne pour simplifier les accès aux pas
167 par la méthode "stepserie", aux attributs par la méthode "tagserie" et
168 aux valeurs par la méthode "valueserie".
171 # Cherche l'item demandé
172 if item is not None and item < len(self.__steps):
175 # Cherche le ou les items dont le "step" est demandé
176 elif step is not None and step in self.__steps:
181 while self.__steps.index(step,searchFrom) >= 0:
182 searchFrom = self.__steps.index(step,searchFrom)
183 allIndexes.append( searchFrom )
185 except ValueError, e:
189 return [self.__steps.index(step),]
191 # Cherche le ou les items dont les "tags" sont demandés
192 elif tags is not None and type(tags) is dict :
194 for i, attributs in enumerate(self.__tags): # Boucle sur les attributs de chaque pas
195 selection = True # Booleen permettant de traiter la combinaison "ET" des tags
196 for key in tags.keys(): # Boucle sur tous les tags de filtrage
197 if key not in self.__tagkeys.keys(): continue # Passe au suivant s'il n'existe nulle part
198 if not( key in attributs.keys() and attributs[key] == tags[key] ):
202 allIndexes = list(set(allIndexes))
206 # Renvoie par défaut tous les items valides
208 return range(len(self.__steps))
210 def stepserie(self, item=None, step=None, tags=None):
212 Les "step" sont les pas nommés de stockage. Par défaut, s'il ne sont pas
213 définis explicitement, ils sont identiques aux index de stockage. Ils
214 sont renvoyés par cette fonction selon les filtres définis par les
217 Les comportements sont les suivants :
218 - Renvoie par défaut toute la liste des pas.
219 - Si l'argument "item" est valide, renvoie le pas à cet index.
220 - Si l'argument "step" existe dans la liste des pas, le renvoie.
221 - Si l'argument "tags" est un dictionnaire correct, renvoie les pas
222 caractérisés par toutes les paires "tag/valeur" des tags indiqués,
225 if item is not None and item < len(self.__steps):
226 return self.__steps[item]
227 elif step is not None and step in self.__steps:
229 elif tags is not None:
230 allIndexes = self.itemserie(tags = tags)
231 return [self.__steps[index] for index in allIndexes]
235 def valueserie(self, item=None, step=None, tags=None,
238 Les valeurs stockées sont renvoyées par cette fonction selon les filtres
239 définis par les mots-clés.
241 Les comportements sont les suivants :
242 - Renvoie par défaut toute la liste des valeurs.
243 - Si l'argument "item" est valide, renvoie la valeur à cet index.
244 - Si l'argument "step" existe dans la liste des pas de stockage,
245 renvoie la première valeur (si allSteps=False) ou toutes les
246 valeurs (si allSteps=True).
247 - Si l'argument "tags" est un dictionnaire correct, renvoie les
248 valeurs aux pas caractérisés par toutes les paires "tag/valeur"
249 des tags indiqués, ou rien sinon.
251 if item is not None and item < len(self.__values):
252 return self.__values[item]
253 elif step is not None:
254 allIndexes = self.itemserie(step = step, allSteps = allSteps)
256 return [self.__values[index] for index in allIndexes]
258 return self.__values[allIndexes[0]]
259 elif tags is not None:
260 allIndexes = self.itemserie(tags = tags)
261 return [self.__values[index] for index in allIndexes]
265 def tagserie(self, item=None, step=None, tags=None,
266 allSteps=False, withValues=False,
269 Les "tag" sont les attributs nommés, sous forme de paires "clé/valeur",
270 qu'il est possible d'associer avec chaque pas de stockage. Par défaut,
271 s'il ne sont pas définis explicitement, il n'y en a pas. Ils sont
272 renvoyés par cette fonction selon les filtres définis par les mots-clés.
273 On obtient uniquement la liste des clés de tags avec "withValues=False"
274 ou la liste des paires "clé/valeurs" avec "withValues=True".
276 On peut aussi obtenir les valeurs d'un tag satisfaisant aux conditions
277 de filtrage en "item/step/tags" en donnant le nom du tag dans
280 Les comportements sont les suivants :
281 - Renvoie par défaut toute la liste des tags.
282 - Si l'argument "item" est valide, renvoie le tag à cet index.
283 - Si l'argument "step" existe dans la liste des pas de stockage,
284 renvoie les tags du premier pas (si allSteps=False) ou la liste
285 des tags de tous les pas (si allSteps=True).
286 - Si l'argument "tags" est un dictionnaire correct, renvoie les
287 valeurs aux pas caractérisés par toutes les paires "tag/valeur"
288 des tags indiqués, ou rien sinon.
291 # Cherche tous les index satisfaisant les conditions
292 allIndexes = self.itemserie(item = item, step = step, tags = tags, allSteps = allSteps)
294 # Dans le cas où la sortie donne les valeurs d'un "outputTag"
295 if outputTag is not None and type(outputTag) is str :
297 for index in allIndexes:
298 if outputTag in self.__tags[index].keys():
299 outputValues.append( self.__tags[index][outputTag] )
300 outputValues = list(set(outputValues))
304 # Dans le cas où la sortie donne les tags satisfaisants aux conditions
307 return [self.__tags[index] for index in allIndexes]
310 for index in allIndexes:
311 allTags.update( self.__tags[index] )
312 allKeys = allTags.keys()
316 def stepnumber(self):
318 Renvoie le nombre de pas de stockage.
320 return len(self.__steps)
322 # ---------------------------------------------------------
323 # Méthodes d'accès de type dictionnaire
325 return self.stepserie()
328 return self.valueserie()
332 for i in xrange(self.stepnumber()):
333 pairs.append( (self.stepserie(item=i), self.valueserie(item=i)) )
336 # ---------------------------------------------------------
339 Renvoie la série, contenant à chaque pas, la valeur moyenne des données
340 au pas. Il faut que le type de base soit compatible avec les types
344 return [numpy.matrix(item).mean() for item in self.__values]
346 raise TypeError("Base type is incompatible with numpy")
348 def stds(self, ddof=0):
350 Renvoie la série, contenant à chaque pas, l'écart-type des données
351 au pas. Il faut que le type de base soit compatible avec les types
354 ddof : c'est le nombre de degrés de liberté pour le calcul de
355 l'écart-type, qui est dans le diviseur. Inutile avant Numpy 1.1
358 if numpy.version.version >= '1.1.0':
359 return [numpy.matrix(item).std(ddof=ddof) for item in self.__values]
361 return [numpy.matrix(item).std() for item in self.__values]
363 raise TypeError("Base type is incompatible with numpy")
367 Renvoie la série, contenant à chaque pas, la somme des données au pas.
368 Il faut que le type de base soit compatible avec les types élémentaires
372 return [numpy.matrix(item).sum() for item in self.__values]
374 raise TypeError("Base type is incompatible with numpy")
378 Renvoie la série, contenant à chaque pas, le minimum des données au pas.
379 Il faut que le type de base soit compatible avec les types élémentaires
383 return [numpy.matrix(item).min() for item in self.__values]
385 raise TypeError("Base type is incompatible with numpy")
389 Renvoie la série, contenant à chaque pas, la maximum des données au pas.
390 Il faut que le type de base soit compatible avec les types élémentaires
394 return [numpy.matrix(item).max() for item in self.__values]
396 raise TypeError("Base type is incompatible with numpy")
403 geometry = "600x400",
408 # Vérification de la disponibilité du module Gnuplot
411 self.__gnuplot = Gnuplot
413 raise ImportError("The Gnuplot module is required to plot the object.")
415 # Vérification et compléments sur les paramètres d'entrée
417 self.__gnuplot.GnuplotOpts.gnuplot_command = 'gnuplot -persist -geometry '+geometry
419 self.__gnuplot.GnuplotOpts.gnuplot_command = 'gnuplot -geometry '+geometry
422 self.__g = self.__gnuplot.Gnuplot() # persist=1
423 self.__g('set terminal '+self.__gnuplot.GnuplotOpts.default_term)
424 self.__g('set style data lines')
426 self.__g('set autoscale')
427 self.__g('set xlabel "'+str(xlabel).encode('ascii','replace')+'"')
428 self.__g('set ylabel "'+str(ylabel).encode('ascii','replace')+'"')
430 self.__ltitle = ltitle
433 def plots(self, item=None, step=None,
439 geometry = "600x400",
446 Renvoie un affichage de la valeur à chaque pas, si elle est compatible
447 avec un affichage Gnuplot (donc essentiellement un vecteur). Si
448 l'argument "step" existe dans la liste des pas de stockage effectués,
449 renvoie l'affichage de la valeur stockée à ce pas "step". Si l'argument
450 "item" est correct, renvoie l'affichage de la valeur stockée au numéro
451 "item". Par défaut ou en l'absence de "step" ou "item", renvoie un
452 affichage successif de tous les pas.
455 - step : valeur du pas à afficher
456 - item : index de la valeur à afficher
457 - steps : liste unique des pas de l'axe des X, ou None si c'est
458 la numérotation par défaut
459 - title : base du titre général, qui sera automatiquement
460 complétée par la mention du pas
461 - xlabel : label de l'axe des X
462 - ylabel : label de l'axe des Y
463 - ltitle : titre associé au vecteur tracé
464 - geometry : taille en pixels de la fenêtre et position du coin haut
465 gauche, au format X11 : LxH+X+Y (défaut : 600x400)
466 - filename : base de nom de fichier Postscript pour une sauvegarde,
467 qui est automatiquement complétée par le numéro du
468 fichier calculé par incrément simple de compteur
469 - dynamic : effectue un affichage des valeurs à chaque stockage
470 (au-delà du second). La méthode "plots" permet de
471 déclarer l'affichage dynamique, et c'est la méthode
472 "__replots" qui est utilisée pour l'effectuer
473 - persist : booléen indiquant que la fenêtre affichée sera
474 conservée lors du passage au dessin suivant
475 Par défaut, persist = False
476 - pause : booléen indiquant une pause après chaque tracé, et
478 Par défaut, pause = True
481 if not self.__dynamic:
482 self.__preplots(title, xlabel, ylabel, ltitle, geometry, persist, pause )
484 self.__dynamic = True
485 if len(self.__values) == 0: return 0
487 # Tracé du ou des vecteurs demandés
489 if step is not None and step in self.__steps:
490 indexes.append(self.__steps.index(step))
491 elif item is not None and item < len(self.__values):
494 indexes = indexes + range(len(self.__values))
497 for index in indexes:
498 self.__g('set title "'+str(title).encode('ascii','replace')+' (pas '+str(index)+')"')
499 if ( type(steps) is list ) or ( type(steps) is type(numpy.array([])) ):
502 Steps = range(len(self.__values[index]))
504 self.__g.plot( self.__gnuplot.Data( Steps, self.__values[index], title=ltitle ) )
508 stepfilename = "%s_%03i.ps"%(filename,i)
509 if os.path.isfile(stepfilename):
510 raise ValueError("Error: a file with this name \"%s\" already exists."%stepfilename)
511 self.__g.hardcopy(filename=stepfilename, color=1)
513 raw_input('Please press return to continue...\n')
517 Affichage dans le cas du suivi dynamique de la variable
519 if self.__dynamic and len(self.__values) < 2: return 0
521 self.__g('set title "'+str(self.__title).encode('ascii','replace'))
522 Steps = range(len(self.__values))
523 self.__g.plot( self.__gnuplot.Data( Steps, self.__values, title=self.__ltitle ) )
526 raw_input('Please press return to continue...\n')
528 # ---------------------------------------------------------
531 Renvoie la moyenne sur toutes les valeurs sans tenir compte de la
532 longueur des pas. Il faut que le type de base soit compatible avec
533 les types élémentaires numpy.
536 if self.__basetype in [int, float]:
537 return float( numpy.array(self.__values).mean() )
539 return numpy.array(self.__values).mean(axis=0)
541 raise TypeError("Base type is incompatible with numpy")
543 def std(self, ddof=0):
545 Renvoie l'écart-type de toutes les valeurs sans tenir compte de la
546 longueur des pas. Il faut que le type de base soit compatible avec
547 les types élémentaires numpy.
549 ddof : c'est le nombre de degrés de liberté pour le calcul de
550 l'écart-type, qui est dans le diviseur. Inutile avant Numpy 1.1
553 if numpy.version.version >= '1.1.0':
554 return numpy.array(self.__values).std(ddof=ddof,axis=0)
556 return numpy.array(self.__values).std(axis=0)
558 raise TypeError("Base type is incompatible with numpy")
562 Renvoie la somme de toutes les valeurs sans tenir compte de la
563 longueur des pas. Il faut que le type de base soit compatible avec
564 les types élémentaires numpy.
567 return numpy.array(self.__values).sum(axis=0)
569 raise TypeError("Base type is incompatible with numpy")
573 Renvoie le minimum de toutes les valeurs sans tenir compte de la
574 longueur des pas. Il faut que le type de base soit compatible avec
575 les types élémentaires numpy.
578 return numpy.array(self.__values).min(axis=0)
580 raise TypeError("Base type is incompatible with numpy")
584 Renvoie le maximum de toutes les valeurs sans tenir compte de la
585 longueur des pas. Il faut que le type de base soit compatible avec
586 les types élémentaires numpy.
589 return numpy.array(self.__values).max(axis=0)
591 raise TypeError("Base type is incompatible with numpy")
595 Renvoie la somme cumulée de toutes les valeurs sans tenir compte de la
596 longueur des pas. Il faut que le type de base soit compatible avec
597 les types élémentaires numpy.
600 return numpy.array(self.__values).cumsum(axis=0)
602 raise TypeError("Base type is incompatible with numpy")
604 # On pourrait aussi utiliser les autres attributs d'une "matrix", comme
613 geometry = "600x400",
619 Renvoie un affichage unique pour l'ensemble des valeurs à chaque pas, si
620 elles sont compatibles avec un affichage Gnuplot (donc essentiellement
621 un vecteur). Si l'argument "step" existe dans la liste des pas de
622 stockage effectués, renvoie l'affichage de la valeur stockée à ce pas
623 "step". Si l'argument "item" est correct, renvoie l'affichage de la
624 valeur stockée au numéro "item".
627 - steps : liste unique des pas de l'axe des X, ou None si c'est
628 la numérotation par défaut
629 - title : base du titre général, qui sera automatiquement
630 complétée par la mention du pas
631 - xlabel : label de l'axe des X
632 - ylabel : label de l'axe des Y
633 - ltitle : titre associé au vecteur tracé
634 - geometry : taille en pixels de la fenêtre et position du coin haut
635 gauche, au format X11 : LxH+X+Y (défaut : 600x400)
636 - filename : nom de fichier Postscript pour une sauvegarde
637 - persist : booléen indiquant que la fenêtre affichée sera
638 conservée lors du passage au dessin suivant
639 Par défaut, persist = False
640 - pause : booléen indiquant une pause après chaque tracé, et
642 Par défaut, pause = True
645 # Vérification de la disponibilité du module Gnuplot
648 self.__gnuplot = Gnuplot
650 raise ImportError("The Gnuplot module is required to plot the object.")
652 # Vérification et compléments sur les paramètres d'entrée
654 self.__gnuplot.GnuplotOpts.gnuplot_command = 'gnuplot -persist -geometry '+geometry
656 self.__gnuplot.GnuplotOpts.gnuplot_command = 'gnuplot -geometry '+geometry
659 if ( type(steps) is list ) or ( type(steps) is type(numpy.array([])) ):
662 Steps = range(len(self.__values[0]))
663 self.__g = self.__gnuplot.Gnuplot() # persist=1
664 self.__g('set terminal '+self.__gnuplot.GnuplotOpts.default_term)
665 self.__g('set style data lines')
667 self.__g('set autoscale')
668 self.__g('set title "'+str(title).encode('ascii','replace') +'"')
669 self.__g('set xlabel "'+str(xlabel).encode('ascii','replace')+'"')
670 self.__g('set ylabel "'+str(ylabel).encode('ascii','replace')+'"')
672 # Tracé du ou des vecteurs demandés
673 indexes = range(len(self.__values))
674 self.__g.plot( self.__gnuplot.Data( Steps, self.__values[indexes.pop(0)], title=ltitle+" (pas 0)" ) )
675 for index in indexes:
676 self.__g.replot( self.__gnuplot.Data( Steps, self.__values[index], title=ltitle+" (pas %i)"%index ) )
679 self.__g.hardcopy(filename=filename, color=1)
681 raw_input('Please press return to continue...\n')
683 # ---------------------------------------------------------
684 def setDataObserver(self,
686 HookParameters = None,
690 Association à la variable d'un triplet définissant un observer
692 Le Scheduler attendu est une fréquence, une simple liste d'index ou un
696 # Vérification du Scheduler
697 # -------------------------
699 if type(Scheduler) is int: # Considéré comme une fréquence à partir de 0
700 Schedulers = xrange( 0, maxiter, int(Scheduler) )
701 elif type(Scheduler) is xrange: # Considéré comme un itérateur
702 Schedulers = Scheduler
703 elif type(Scheduler) is list: # Considéré comme des index explicites
704 Schedulers = map( long, Scheduler )
705 else: # Dans tous les autres cas, activé par défaut
706 Schedulers = xrange( 0, maxiter )
708 # Stockage interne de l'observer dans la variable
709 # -----------------------------------------------
710 self.__dataobservers.append( [HookFunction, HookParameters, Schedulers] )
712 def removeDataObserver(self,
716 Suppression d'un observer nommé sur la variable.
718 On peut donner dans HookFunction la meme fonction que lors de la
719 définition, ou un simple string qui est le nom de la fonction.
722 if hasattr(HookFunction,"func_name"):
723 name = str( HookFunction.func_name )
724 elif type(HookFunction) is str:
725 name = str( HookFunction )
731 for [hf, hp, hs] in self.__dataobservers:
733 if name is hf.func_name: index_to_remove.append( i )
734 index_to_remove.reverse()
735 for i in index_to_remove:
736 self.__dataobservers.pop( i )
738 # ==============================================================================
739 class OneScalar(Persistence):
741 Classe définissant le stockage d'une valeur unique réelle (float) par pas
743 Le type de base peut être changé par la méthode "basetype", mais il faut que
744 le nouveau type de base soit compatible avec les types par éléments de
745 numpy. On peut même utiliser cette classe pour stocker des vecteurs/listes
746 ou des matrices comme dans les classes suivantes, mais c'est déconseillé
747 pour conserver une signification claire des noms.
749 def __init__(self, name="", unit="", basetype = float):
750 Persistence.__init__(self, name, unit, basetype)
752 class OneVector(Persistence):
754 Classe définissant le stockage d'une liste (list) de valeurs homogènes par
755 hypothèse par pas. Pour éviter les confusions, ne pas utiliser la classe
756 "OneVector" pour des données hétérogènes, mais bien "OneList".
758 def __init__(self, name="", unit="", basetype = list):
759 Persistence.__init__(self, name, unit, basetype)
761 class OneMatrix(Persistence):
763 Classe définissant le stockage d'une matrice de valeurs (numpy.matrix) par
766 def __init__(self, name="", unit="", basetype = numpy.matrix):
767 Persistence.__init__(self, name, unit, basetype)
769 class OneList(Persistence):
771 Classe définissant le stockage d'une liste de valeurs potentiellement
772 hétérogènes (list) par pas. Pour éviter les confusions, ne pas utiliser la
773 classe "OneVector" pour des données hétérogènes, mais bien "OneList".
775 def __init__(self, name="", unit="", basetype = list):
776 Persistence.__init__(self, name, unit, basetype)
778 def NoType( value ): return value
780 class OneNoType(Persistence):
782 Classe définissant le stockage d'un objet sans modification (cast) de type.
783 Attention, selon le véritable type de l'objet stocké à chaque pas, les
784 opérations arithmétiques à base de numpy peuvent être invalides ou donner
785 des résultats inatendus. Cette classe n'est donc à utiliser qu'à bon escient
786 volontairement, et pas du tout par défaut.
788 def __init__(self, name="", unit="", basetype = NoType):
789 Persistence.__init__(self, name, unit, basetype)
791 # ==============================================================================
792 class CompositePersistence:
794 Structure de stockage permettant de rassembler plusieurs objets de
797 Des objets par défaut sont prévus, et des objets supplémentaires peuvent
800 def __init__(self, name="", defaults=True):
804 La gestion interne des données est exclusivement basée sur les variables
805 initialisées ici (qui ne sont pas accessibles depuis l'extérieur des
806 objets comme des attributs) :
807 __StoredObjects : objets de type persistence collectés dans cet objet
809 self.__name = str(name)
811 self.__StoredObjects = {}
813 # Definition des objets par defaut
814 # --------------------------------
816 self.__StoredObjects["Informations"] = OneNoType("Informations")
817 self.__StoredObjects["Background"] = OneVector("Background", basetype=numpy.array)
818 self.__StoredObjects["BackgroundError"] = OneMatrix("BackgroundError")
819 self.__StoredObjects["Observation"] = OneVector("Observation", basetype=numpy.array)
820 self.__StoredObjects["ObservationError"] = OneMatrix("ObservationError")
821 self.__StoredObjects["Analysis"] = OneVector("Analysis", basetype=numpy.array)
822 self.__StoredObjects["AnalysisError"] = OneMatrix("AnalysisError")
823 self.__StoredObjects["Innovation"] = OneVector("Innovation", basetype=numpy.array)
824 self.__StoredObjects["KalmanGainK"] = OneMatrix("KalmanGainK")
825 self.__StoredObjects["OperatorH"] = OneMatrix("OperatorH")
826 self.__StoredObjects["RmsOMA"] = OneScalar("RmsOMA")
827 self.__StoredObjects["RmsOMB"] = OneScalar("RmsOMB")
828 self.__StoredObjects["RmsBMA"] = OneScalar("RmsBMA")
831 def store(self, name=None, value=None, step=None, tags={}):
833 Stockage d'une valeur "value" pour le "step" dans la variable "name".
835 if name is None: raise ValueError("Storable object name is required for storage.")
836 if name not in self.__StoredObjects.keys():
837 raise ValueError("No such name '%s' exists in storable objects."%name)
838 self.__StoredObjects[name].store( value=value, step=step, tags=tags )
840 def add_object(self, name=None, persistenceType=Persistence, basetype=numpy.array ):
842 Ajoute dans les objets stockables un nouvel objet défini par son nom, son
843 type de Persistence et son type de base à chaque pas.
845 if name is None: raise ValueError("Object name is required for adding an object.")
846 if name in self.__StoredObjects.keys():
847 raise ValueError("An object with the same name '%s' already exists in storable objects. Choose another one."%name)
848 self.__StoredObjects[name] = persistenceType( name=str(name), basetype=basetype )
850 def get_object(self, name=None ):
852 Renvoie l'objet de type Persistence qui porte le nom demandé.
854 if name is None: raise ValueError("Object name is required for retrieving an object.")
855 if name not in self.__StoredObjects.keys():
856 raise ValueError("No such name '%s' exists in stored objects."%name)
857 return self.__StoredObjects[name]
859 def set_object(self, name=None, objet=None ):
861 Affecte directement un 'objet' qui porte le nom 'name' demandé.
862 Attention, il n'est pas effectué de vérification sur le type, qui doit
863 comporter les méthodes habituelles de Persistence pour que cela
866 if name is None: raise ValueError("Object name is required for setting an object.")
867 if name in self.__StoredObjects.keys():
868 raise ValueError("An object with the same name '%s' already exists in storable objects. Choose another one."%name)
869 self.__StoredObjects[name] = objet
871 def del_object(self, name=None ):
873 Supprime un objet de la liste des objets stockables.
875 if name is None: raise ValueError("Object name is required for retrieving an object.")
876 if name not in self.__StoredObjects.keys():
877 raise ValueError("No such name '%s' exists in stored objects."%name)
878 del self.__StoredObjects[name]
880 # ---------------------------------------------------------
881 # Méthodes d'accès de type dictionnaire
882 def __getitem__(self, name=None ):
883 return self.get_object( name )
885 def __setitem__(self, name=None, objet=None ):
886 self.set_object( name, objet )
889 return self.get_stored_objects(hideVoidObjects = False)
892 return self.__StoredObjects.values()
895 return self.__StoredObjects.items()
897 # ---------------------------------------------------------
898 def get_stored_objects(self, hideVoidObjects = False):
899 objs = self.__StoredObjects.keys()
904 if len(self.__StoredObjects[k]) > 0: usedObjs.append( k )
911 # ---------------------------------------------------------
912 def save_composite(self, filename=None, mode="pickle", compress="gzip"):
914 Enregistre l'objet dans le fichier indiqué selon le "mode" demandé,
915 et renvoi le nom du fichier
919 if compress == "gzip":
920 filename = os.tempnam( os.getcwd(), 'dacp' ) + ".pkl.gz"
921 elif compress == "bzip2":
922 filename = os.tempnam( os.getcwd(), 'dacp' ) + ".pkl.bz2"
924 filename = os.tempnam( os.getcwd(), 'dacp' ) + ".pkl"
926 filename = os.path.abspath( filename )
930 if compress == "gzip":
932 output = gzip.open( filename, 'wb')
933 elif compress == "bzip2":
935 output = bz2.BZ2File( filename, 'wb')
937 output = open( filename, 'wb')
938 cPickle.dump(self, output)
941 raise ValueError("Save mode '%s' unknown. Choose another one."%mode)
945 def load_composite(self, filename=None, mode="pickle", compress="gzip"):
947 Recharge un objet composite sauvé en fichier
951 raise ValueError("A file name if requested to load a composite.")
953 filename = os.path.abspath( filename )
957 if compress == "gzip":
959 pkl_file = gzip.open( filename, 'rb')
960 elif compress == "bzip2":
962 pkl_file = bz2.BZ2File( filename, 'rb')
964 pkl_file = open(filename, 'rb')
965 output = cPickle.load(pkl_file)
966 for k in output.keys():
969 raise ValueError("Load mode '%s' unknown. Choose another one."%mode)
973 # ==============================================================================
974 if __name__ == "__main__":
975 print '\n AUTODIAGNOSTIC \n'
977 print "======> Un flottant"
978 OBJET_DE_TEST = OneScalar("My float", unit="cm")
979 OBJET_DE_TEST.store( 5.)
980 OBJET_DE_TEST.store(-5.)
981 OBJET_DE_TEST.store( 1.)
982 print "Les pas de stockage :", OBJET_DE_TEST.stepserie()
983 print "Les valeurs :", OBJET_DE_TEST.valueserie()
984 print "La 2ème valeur :", OBJET_DE_TEST.valueserie(1)
985 print "La dernière valeur :", OBJET_DE_TEST.valueserie(-1)
986 print "Valeurs par pas :"
987 print " La moyenne :", OBJET_DE_TEST.means()
988 print " L'écart-type :", OBJET_DE_TEST.stds()
989 print " La somme :", OBJET_DE_TEST.sums()
990 print " Le minimum :", OBJET_DE_TEST.mins()
991 print " Le maximum :", OBJET_DE_TEST.maxs()
992 print "Valeurs globales :"
993 print " La moyenne :", OBJET_DE_TEST.mean()
994 print " L'écart-type :", OBJET_DE_TEST.std()
995 print " La somme :", OBJET_DE_TEST.sum()
996 print " Le minimum :", OBJET_DE_TEST.min()
997 print " Le maximum :", OBJET_DE_TEST.max()
998 print " La somme cumulée :", OBJET_DE_TEST.cumsum()
999 print "Taille \"shape\" :", OBJET_DE_TEST.shape()
1000 print "Taille \"len\" :", len(OBJET_DE_TEST)
1004 print "======> Un flottant"
1005 OBJET_DE_TEST = OneScalar("My float", unit="cm")
1006 OBJET_DE_TEST.store( 5., step="azerty")
1007 OBJET_DE_TEST.store(-5., step="poiuyt")
1008 OBJET_DE_TEST.store( 1., step="azerty")
1009 OBJET_DE_TEST.store( 0., step="xxxxxx")
1010 OBJET_DE_TEST.store( 5., step="poiuyt")
1011 OBJET_DE_TEST.store(-5., step="azerty")
1012 OBJET_DE_TEST.store( 1., step="poiuyt")
1013 print "Les pas de stockage :", OBJET_DE_TEST.stepserie()
1014 print "Les valeurs :", OBJET_DE_TEST.valueserie()
1015 print "La 2ème valeur :", OBJET_DE_TEST.valueserie(1)
1016 print "La dernière valeur :", OBJET_DE_TEST.valueserie(-1)
1017 print "Premier index :", OBJET_DE_TEST.valueserie( step = "azerty", allSteps = False )
1018 print "Valeurs identiques :", OBJET_DE_TEST.valueserie( step = "azerty", allSteps = True )
1019 print "Premier index :", OBJET_DE_TEST.valueserie( step = "poiuyt", allSteps = False )
1020 print "Valeurs identiques :", OBJET_DE_TEST.valueserie( step = "poiuyt", allSteps = True )
1024 print "======> Un entier"
1025 OBJET_DE_TEST = OneScalar("My int", unit="cm", basetype=int)
1026 OBJET_DE_TEST.store( 5 )
1027 OBJET_DE_TEST.store(-5 )
1028 OBJET_DE_TEST.store( 1.)
1029 print "Les pas de stockage :", OBJET_DE_TEST.stepserie()
1030 print "Les valeurs :", OBJET_DE_TEST.valueserie()
1031 print "La 2ème valeur :", OBJET_DE_TEST.valueserie(1)
1032 print "La dernière valeur :", OBJET_DE_TEST.valueserie(-1)
1033 print "Valeurs par pas :"
1034 print " La moyenne :", OBJET_DE_TEST.means()
1035 print " L'écart-type :", OBJET_DE_TEST.stds()
1036 print " La somme :", OBJET_DE_TEST.sums()
1037 print " Le minimum :", OBJET_DE_TEST.mins()
1038 print " Le maximum :", OBJET_DE_TEST.maxs()
1039 print "Valeurs globales :"
1040 print " La moyenne :", OBJET_DE_TEST.mean()
1041 print " L'écart-type :", OBJET_DE_TEST.std()
1042 print " La somme :", OBJET_DE_TEST.sum()
1043 print " Le minimum :", OBJET_DE_TEST.min()
1044 print " Le maximum :", OBJET_DE_TEST.max()
1045 print " La somme cumulée :", OBJET_DE_TEST.cumsum()
1046 print "Taille \"shape\" :", OBJET_DE_TEST.shape()
1047 print "Taille \"len\" :", len(OBJET_DE_TEST)
1051 print "======> Un booléen"
1052 OBJET_DE_TEST = OneScalar("My bool", unit="", basetype=bool)
1053 OBJET_DE_TEST.store( True )
1054 OBJET_DE_TEST.store( False )
1055 OBJET_DE_TEST.store( True )
1056 print "Les pas de stockage :", OBJET_DE_TEST.stepserie()
1057 print "Les valeurs :", OBJET_DE_TEST.valueserie()
1058 print "La 2ème valeur :", OBJET_DE_TEST.valueserie(1)
1059 print "La dernière valeur :", OBJET_DE_TEST.valueserie(-1)
1060 print "Taille \"shape\" :", OBJET_DE_TEST.shape()
1061 print "Taille \"len\" :", len(OBJET_DE_TEST)
1065 print "======> Un vecteur de flottants"
1066 OBJET_DE_TEST = OneVector("My float vector", unit="cm")
1067 OBJET_DE_TEST.store( (5 , -5) )
1068 OBJET_DE_TEST.store( (-5, 5 ) )
1069 OBJET_DE_TEST.store( (1., 1.) )
1070 print "Les pas de stockage :", OBJET_DE_TEST.stepserie()
1071 print "Les valeurs :", OBJET_DE_TEST.valueserie()
1072 print "La 2ème valeur :", OBJET_DE_TEST.valueserie(1)
1073 print "La dernière valeur :", OBJET_DE_TEST.valueserie(-1)
1074 print "Valeurs par pas :"
1075 print " La moyenne :", OBJET_DE_TEST.means()
1076 print " L'écart-type :", OBJET_DE_TEST.stds()
1077 print " La somme :", OBJET_DE_TEST.sums()
1078 print " Le minimum :", OBJET_DE_TEST.mins()
1079 print " Le maximum :", OBJET_DE_TEST.maxs()
1080 print "Valeurs globales :"
1081 print " La moyenne :", OBJET_DE_TEST.mean()
1082 print " L'écart-type :", OBJET_DE_TEST.std()
1083 print " La somme :", OBJET_DE_TEST.sum()
1084 print " Le minimum :", OBJET_DE_TEST.min()
1085 print " Le maximum :", OBJET_DE_TEST.max()
1086 print " La somme cumulée :", OBJET_DE_TEST.cumsum()
1087 print "Taille \"shape\" :", OBJET_DE_TEST.shape()
1088 print "Taille \"len\" :", len(OBJET_DE_TEST)
1092 print "======> Une liste hétérogène"
1093 OBJET_DE_TEST = OneList("My list", unit="bool/cm")
1094 OBJET_DE_TEST.store( (True , -5) )
1095 OBJET_DE_TEST.store( (False, 5 ) )
1096 OBJET_DE_TEST.store( (True , 1.) )
1097 print "Les pas de stockage :", OBJET_DE_TEST.stepserie()
1098 print "Les valeurs :", OBJET_DE_TEST.valueserie()
1099 print "La 2ème valeur :", OBJET_DE_TEST.valueserie(1)
1100 print "La dernière valeur :", OBJET_DE_TEST.valueserie(-1)
1101 print "Valeurs par pas : attention, on peut les calculer car True=1, False=0, mais cela n'a pas de sens"
1102 print " La moyenne :", OBJET_DE_TEST.means()
1103 print " L'écart-type :", OBJET_DE_TEST.stds()
1104 print " La somme :", OBJET_DE_TEST.sums()
1105 print " Le minimum :", OBJET_DE_TEST.mins()
1106 print " Le maximum :", OBJET_DE_TEST.maxs()
1107 print "Valeurs globales : attention, on peut les calculer car True=1, False=0, mais cela n'a pas de sens"
1108 print " La moyenne :", OBJET_DE_TEST.mean()
1109 print " L'écart-type :", OBJET_DE_TEST.std()
1110 print " La somme :", OBJET_DE_TEST.sum()
1111 print " Le minimum :", OBJET_DE_TEST.min()
1112 print " Le maximum :", OBJET_DE_TEST.max()
1113 print " La somme cumulée :", OBJET_DE_TEST.cumsum()
1114 print "Taille \"shape\" :", OBJET_DE_TEST.shape()
1115 print "Taille \"len\" :", len(OBJET_DE_TEST)
1119 print "======> Utilisation directe de la classe Persistence"
1120 OBJET_DE_TEST = Persistence("My object", unit="", basetype=int )
1121 OBJET_DE_TEST.store( 1 )
1122 OBJET_DE_TEST.store( 3 )
1123 OBJET_DE_TEST.store( 7 )
1124 print "Les pas de stockage :", OBJET_DE_TEST.stepserie()
1125 print "Les valeurs :", OBJET_DE_TEST.valueserie()
1126 print "La 2ème valeur :", OBJET_DE_TEST.valueserie(1)
1127 print "La dernière valeur :", OBJET_DE_TEST.valueserie(-1)
1128 print "Taille \"shape\" :", OBJET_DE_TEST.shape()
1129 print "Taille \"len\" :", len(OBJET_DE_TEST)
1133 print "======> Utilisation des méthodes d'accès de type dictionnaire"
1134 OBJET_DE_TEST = OneScalar("My int", unit="cm", basetype=int)
1136 OBJET_DE_TEST.store( 7+i )
1137 print "Taille \"len\" :", len(OBJET_DE_TEST)
1138 print "Les pas de stockage :", OBJET_DE_TEST.keys()
1139 print "Les valeurs :", OBJET_DE_TEST.values()
1140 print "Les paires :", OBJET_DE_TEST.items()
1141 OBJET_DE_TEST.pop(step=1)
1142 print "Les valeurs sans la 1:", OBJET_DE_TEST.values()
1143 OBJET_DE_TEST.pop(item=2)
1144 print "Les valeurs sans la 2:", OBJET_DE_TEST.values()
1148 print "======> Persistence composite"
1149 OBJET_DE_TEST = CompositePersistence("My CompositePersistence")
1150 print "Objets stockables :", OBJET_DE_TEST.get_stored_objects()
1151 print "Objets actifs :", OBJET_DE_TEST.get_stored_objects( hideVoidObjects = True )
1152 print "--> Stockage d'une valeur de Background"
1153 OBJET_DE_TEST.store("Background",numpy.zeros(5))
1154 print "Objets actifs :", OBJET_DE_TEST.get_stored_objects( hideVoidObjects = True )
1155 print "--> Ajout d'un objet nouveau par defaut, de type vecteur numpy par pas"
1156 OBJET_DE_TEST.add_object("ValeursVectorielles")
1157 OBJET_DE_TEST.store("ValeursVectorielles",numpy.zeros(5))
1158 print "Objets actifs :", OBJET_DE_TEST.get_stored_objects( hideVoidObjects = True )
1159 print "--> Ajout d'un objet nouveau de type liste par pas"
1160 OBJET_DE_TEST.add_object("ValeursList", persistenceType=OneList )
1161 OBJET_DE_TEST.store("ValeursList",range(5))
1162 print "Objets actifs :", OBJET_DE_TEST.get_stored_objects( hideVoidObjects = True )
1163 print "--> Ajout d'un objet nouveau, de type vecteur string par pas"
1164 OBJET_DE_TEST.add_object("ValeursStr", persistenceType=Persistence, basetype=str )
1165 OBJET_DE_TEST.store("ValeursStr","IGN3")
1166 OBJET_DE_TEST.store("ValeursStr","c021")
1167 print "Les valeurs :", OBJET_DE_TEST.get_object("ValeursStr").valueserie()
1168 print "Acces comme dict :", OBJET_DE_TEST["ValeursStr"].stepserie()
1169 print "Acces comme dict :", OBJET_DE_TEST["ValeursStr"].valueserie()
1170 print "Objets actifs :", OBJET_DE_TEST.get_stored_objects( hideVoidObjects = True )
1171 print "--> Suppression d'un objet"
1172 OBJET_DE_TEST.del_object("ValeursVectorielles")
1173 print "Objets actifs :", OBJET_DE_TEST.get_stored_objects( hideVoidObjects = True )
1174 print "--> Enregistrement de l'objet complet de Persistence composite"
1175 OBJET_DE_TEST.save_composite("composite.pkl", compress="None")
1178 print "======> Affichage graphique d'objets stockés"
1179 OBJET_DE_TEST = Persistence("My object", unit="", basetype=numpy.array)
1181 vect1 = [1, 2, 1, 2, 1]
1182 vect2 = [-3, -3, 0, -3, -3]
1183 vect3 = [-1, 1, -5, 1, -1]
1184 vect4 = 100*[0.29, 0.97, 0.73, 0.01, 0.20]
1185 print "Stockage de 3 vecteurs de longueur identique"
1189 print "Affichage graphique de l'ensemble du stockage sur une même image"
1191 title = "Tous les vecteurs",
1192 filename="vecteurs.ps",
1196 print "Stockage d'un quatrième vecteur de longueur différente"
1198 print "Affichage graphique séparé du dernier stockage"
1202 filename = "vecteur",
1206 print "Les images ont été stockées en fichiers Postscript"
1207 print "Taille \"shape\" du dernier objet stocké",OBJET_DE_TEST.shape()
1208 print "Taille \"len\" du dernier objet stocké",len(OBJET_DE_TEST)
1212 print "======> Affichage graphique dynamique d'objets"
1213 OBJET_DE_TEST = Persistence("My object", unit="", basetype=float)
1217 title = "Valeur suivie",
1222 for i in range(1,11):
1224 print "Taille \"shape\" du dernier objet stocké",OBJET_DE_TEST.shape()
1225 print "Taille \"len\" du dernier objet stocké",len(OBJET_DE_TEST)
1226 print "Nombre d'objets stockés",OBJET_DE_TEST.stepnumber()
1230 print "======> Affectation simple d'observateurs dynamiques"
1231 def obs(var=None,info=None):
1232 print " ---> Mise en oeuvre de l'observer"
1233 print " var =",var.valueserie(-1)
1234 print " info =",info
1235 OBJET_DE_TEST = Persistence("My object", unit="", basetype=list)
1237 D.setDataObserver( HookFunction = obs )
1240 print "Action de 1 observer sur la variable observée, étape :",i
1241 D.store( [i, i, i] )
1245 print "======> Affectation multiple d'observateurs dynamiques"
1246 def obs(var=None,info=None):
1247 print " ---> Mise en oeuvre de l'observer"
1248 print " var =",var.valueserie(-1)
1249 print " info =",info
1250 def obs_bis(var=None,info=None):
1251 print " ---> Mise en oeuvre de l'observer"
1252 print " var =",var.valueserie(-1)
1253 print " info =",info
1254 OBJET_DE_TEST = Persistence("My object", unit="", basetype=list)
1259 HookParameters = "Premier observer",
1263 Scheduler = xrange(1,3),
1264 HookParameters = "Second observer",
1267 HookFunction = obs_bis,
1268 Scheduler = range(1,3)+range(7,9),
1269 HookParameters = "Troisième observer",
1272 print "Action de 3 observers sur la variable observée, étape :",i
1273 D.store( [i, i, i] )
1274 D.removeDataObserver(
1277 for i in range(5,10):
1278 print "Action d'un seul observer sur la variable observée, étape :",i
1279 D.store( [i, i, i] )
1283 print "======> Utilisation des tags/attributs et stockage puis récupération de l'ensemble"
1284 OBJET_DE_TEST = CompositePersistence("My CompositePersistence", defaults=False)
1285 OBJET_DE_TEST.add_object("My ecarts", basetype = numpy.array)
1287 OBJET_DE_TEST.store( "My ecarts", numpy.arange(1,5), tags = {"Camp":"Base","Carte":"IGN3","Niveau":1024,"Palier":"Premier"} )
1288 OBJET_DE_TEST.store( "My ecarts", numpy.arange(1,5)+1, tags = {"Camp":"Base","Carte":"IGN4","Niveau": 210,"Palier":"Premier"} )
1289 OBJET_DE_TEST.store( "My ecarts", numpy.arange(1,5)+2, tags = {"Camp":"Base","Carte":"IGN1","Niveau":1024} )
1290 OBJET_DE_TEST.store( "My ecarts", numpy.arange(1,5)+3, tags = {"Camp":"Sommet","Carte":"IGN2","Niveau":4024,"Palier":"Second","FullMap":True} )
1292 print "Les pas de stockage :", OBJET_DE_TEST["My ecarts"].stepserie()
1293 print "Les valeurs :", OBJET_DE_TEST["My ecarts"].valueserie()
1294 print "La 2ème valeur :", OBJET_DE_TEST["My ecarts"].valueserie(1)
1295 print "La dernière valeur :", OBJET_DE_TEST["My ecarts"].valueserie(-1)
1296 print "Liste des attributs :", OBJET_DE_TEST["My ecarts"].tagserie()
1297 print "Taille \"shape\" :", OBJET_DE_TEST["My ecarts"].shape()
1298 print "Taille \"len\" :", len(OBJET_DE_TEST["My ecarts"])
1301 print "Pas pour tag :", OBJET_DE_TEST["My ecarts"].stepserie( tags={"Palier":"Premier"} )
1302 print "Valeurs pour tag :", OBJET_DE_TEST["My ecarts"].valueserie( tags={"Palier":"Premier"} )
1304 print "Pas pour tag :", OBJET_DE_TEST["My ecarts"].stepserie( tags={"Carte":"IGN1"} )
1305 print "Pas pour tag :", OBJET_DE_TEST["My ecarts"].stepserie( tags={"Niveau":1024} )
1306 print "Pas pour tag :", OBJET_DE_TEST["My ecarts"].stepserie( tags={"Camp":"Base"} )
1307 print "Pas pour tag :", OBJET_DE_TEST["My ecarts"].stepserie( tags={"Camp":"TOTO"} )
1308 print "Pas pour tag :", OBJET_DE_TEST["My ecarts"].stepserie( tags={"Toto":"Premier"} )
1309 print "Pas pour tag :", OBJET_DE_TEST["My ecarts"].stepserie( tags={"Carte":"IGN1"} )
1312 print "Combinaison 'ET' de plusieurs Tags"
1313 print "Attendu : [0, 1], trouvé :",OBJET_DE_TEST["My ecarts"].stepserie( tags={"Camp":"Base", "Palier":"Premier"} )
1314 print "Attendu : [], trouvé :",OBJET_DE_TEST["My ecarts"].stepserie( tags={"Camp":"Sommet", "Palier":"Premier"} )
1315 # Attention : {"Camp":"Sommet", "Camp":"Base"} == {"Camp":"Base"}
1316 print "Attendu : [0, 1, 2], trouvé :",OBJET_DE_TEST["My ecarts"].stepserie( tags={"Camp":"Sommet", "Camp":"Base"} )
1317 print "Attendu : [2], trouvé :",OBJET_DE_TEST["My ecarts"].stepserie( tags={"Carte":"IGN1", "Niveau":1024} )
1320 print "Liste des tags pour le pas (item) 1 :",OBJET_DE_TEST["My ecarts"].tagserie(item = 1)
1321 print "Liste des tags pour le pas (item) 2 :",OBJET_DE_TEST["My ecarts"].tagserie(item = 2)
1322 print "Comme le step et l'item sont identiques par défaut, on doit avoir la même chose :"
1323 print "Liste des tags pour le pas (step) 1 :",OBJET_DE_TEST["My ecarts"].tagserie(step = 1)
1324 print "Liste des tags pour le pas (step) 2 :",OBJET_DE_TEST["My ecarts"].tagserie(step = 2)
1326 print "Liste des tags/valeurs pour le pas 1 :",OBJET_DE_TEST["My ecarts"].tagserie(item = 1, withValues=True)
1327 print "Liste des tags/valeurs pour le pas 2 :",OBJET_DE_TEST["My ecarts"].tagserie(item = 2, withValues=True)
1330 print "Liste des valeurs possibles pour 1 tag donné 'Camp' :",OBJET_DE_TEST["My ecarts"].tagserie(outputTag="Camp")
1331 print "Liste des valeurs possibles pour 1 tag donné 'Toto' :",OBJET_DE_TEST["My ecarts"].tagserie(outputTag="Toto")
1332 print "Liste des valeurs possibles pour 1 tag donné 'Niveau' :",OBJET_DE_TEST["My ecarts"].tagserie(outputTag="Niveau")
1335 OBJET_DE_TEST.add_object("My other ecarts", basetype = numpy.array)
1336 OBJET_DE_TEST.store( "My other ecarts", numpy.arange(-1,5), tags = {"Camp":"Base","Carte":"IGN3","Niveau":1024,"Palier":"Premier"} )
1337 OBJET_DE_TEST.store( "My other ecarts", numpy.arange(-1,5)+1, tags = {"Camp":"Base","Carte":"IGN4","Niveau": 210,"Palier":"Premier"} )
1338 OBJET_DE_TEST.store( "My other ecarts", numpy.arange(-1,5)+2, tags = {"Camp":"Base","Carte":"IGN1","Niveau":1024} )
1339 OBJET_DE_TEST.store( "My other ecarts", numpy.arange(-1,5)+3, tags = {"Camp":"Sommet","Carte":"IGN2","Niveau":4024,"Palier":"Second"} )
1341 print "Objets présents dans le composite :",OBJET_DE_TEST.get_stored_objects()
1342 fichier = "composite.pkl.gz"
1343 print "Sauvegarde sur \"%s\"..."%fichier
1344 OBJET_DE_TEST.save_composite( fichier )
1345 print "Effacement de l'objet en memoire"
1349 print "Relecture de l'objet sur \"%s\"..."%fichier
1350 OBJET_DE_TEST = CompositePersistence("My CompositePersistence bis", defaults=False)
1351 OBJET_DE_TEST.load_composite( fichier )
1352 print "Objets présents dans le composite :",OBJET_DE_TEST.get_stored_objects()
1353 print "Taille des objets contenus :"
1354 for name in OBJET_DE_TEST.get_stored_objects():
1355 print " Objet \"%s\" : taille unitaire de %i"%(name,len(OBJET_DE_TEST[name]))
1358 print "Les pas de stockage :", OBJET_DE_TEST["My ecarts"].stepserie()
1359 print "Les valeurs :", OBJET_DE_TEST["My ecarts"].valueserie()
1360 print "La 2ème valeur :", OBJET_DE_TEST["My ecarts"].valueserie(1)
1361 print "La dernière valeur :", OBJET_DE_TEST["My ecarts"].valueserie(-1)
1362 print "Liste des attributs :", OBJET_DE_TEST["My ecarts"].tagserie()
1363 print "Taille \"shape\" :", OBJET_DE_TEST["My ecarts"].shape()
1364 print "Taille \"len\" :", len(OBJET_DE_TEST["My ecarts"])
1367 print "Pas pour tag :", OBJET_DE_TEST["My ecarts"].stepserie( tags={"Palier":"Premier"} )
1368 print "Valeurs pour tag :", OBJET_DE_TEST["My ecarts"].valueserie( tags={"Palier":"Premier"} )
1370 print "Pas pour tag :", OBJET_DE_TEST["My ecarts"].stepserie( tags={"Carte":"IGN1"} )
1371 print "Pas pour tag :", OBJET_DE_TEST["My ecarts"].stepserie( tags={"Niveau":1024} )
1372 print "Pas pour tag :", OBJET_DE_TEST["My ecarts"].stepserie( tags={"Camp":"Base"} )
1373 print "Pas pour tag :", OBJET_DE_TEST["My ecarts"].stepserie( tags={"Camp":"TOTO"} )
1374 print "Pas pour tag :", OBJET_DE_TEST["My ecarts"].stepserie( tags={"Toto":"Premier"} )
1375 print "Pas pour tag :", OBJET_DE_TEST["My ecarts"].stepserie( tags={"Carte":"IGN1"} )
1377 print "Attributs :", OBJET_DE_TEST["My ecarts"].tagserie()
1378 print "Attributs pour tag filtré :", OBJET_DE_TEST["My ecarts"].tagserie( tags={"Camp":"Base"} )
1379 print "Attributs pour tag filtré :", OBJET_DE_TEST["My ecarts"].tagserie( tags={"Niveau":4024} )
1381 print "Attributs et valeurs :", OBJET_DE_TEST["My ecarts"].tagserie( withValues=True )
1382 print "Attributs et valeurs pour tag filtré :", OBJET_DE_TEST["My ecarts"].tagserie( withValues=True, tags={"Camp":"Base"} )
1383 print "Attributs et valeurs pour tag filtré :", OBJET_DE_TEST["My ecarts"].tagserie( withValues=True, tags={"Niveau":4024} )
1385 print "Valeur d'attribut pour un tag donné 'BU' :", OBJET_DE_TEST["My ecarts"].tagserie( outputTag = "Niveau" )
1386 print "Valeur d'attribut pour un tag donné 'BU' filtré :", OBJET_DE_TEST["My ecarts"].tagserie( outputTag = "Niveau", tags={"Camp":"Base"} )
1387 print "Valeur d'attribut pour un tag donné 'BU' filtré :", OBJET_DE_TEST["My ecarts"].tagserie( outputTag = "Niveau", tags={"Palier":"Second"} )
1388 print "Valeur d'attribut pour un tag donné 'Camp' filtré :", OBJET_DE_TEST["My ecarts"].tagserie( outputTag = "Camp", tags={"Palier":"Premier"} )
1389 print "Valeur d'attribut pour un tag donné 'Carte' filtré :", OBJET_DE_TEST["My ecarts"].tagserie( outputTag = "Carte", tags={"Palier":"Premier"} )
1390 print "Valeur d'attribut pour un tag donné 'Carte' filtré :", OBJET_DE_TEST["My ecarts"].tagserie( outputTag = "Carte", tags={"Palier":"Premier","Niveau":4024} )
1391 print "Valeur d'attribut pour un tag donné 'Carte' filtré :", OBJET_DE_TEST["My ecarts"].tagserie( outputTag = "Carte", tags={"Palier":"Premier","Niveau":210} )