1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 """The module defining the L{Record} class. L{Record} allows to select
23 the attributes that need to be saved on an object.
24 See the description of L{RecordBase} for the reason of not using
25 the pickle mechanism."""
26
27 from types import DictType
28 from mbdyn.quantity import Results
29
30
32 """A dictionary on which attributes can be added.
33 Those attributes will be references to the others objects to save,
34 a kind of tree is built.
35 """
36 pass
37
38
40 """An object that have the values of its own
41 attributes in a dictionary C{ParametersToSave}.
42 The goal is to select the attributes to save
43 when pickling that object in a file. This object had to be developed,
44 instead of using the default Python mechanism, because some of
45 the attributes could not be pickled (like references to function or
46 attributes from third part libraries -vtk, gtk-)
47 """
48
52
54 """Loop in all the parameters of the class and set them in
55 the C{para} dictionary. The keywords 'own' refers to the objects
56 that can directly be pickled on the object ('self').
57 Others keywords may refer to others objects that will also have to
58 collect their own para parameters.
59 """
60 for own_para_name in self.own_para_names:
61 self.para[own_para_name] = self.__dict__[own_para_name]
62 self.para["own_para_names"] = self.own_para_names
63
65 """C{para} is a C{ParametersToSave} instance.
66 The C{para} received is loaded from a pickled file.
67 Just the owned parameter names are set in that method,
68 but C{para} is a dictionary that can have others keys
69 related to children.
70 """
71 self.para = para
72 self.own_para_names = para["own_para_names"]
73 for own_para_name in self.own_para_names:
74 try:
75 parameter = para[own_para_name]
76 except KeyError:
77 print self, own_para_name
78 raise
79 try:
80 self.__dict__[own_para_name] = parameter
81 except KeyError:
82 print self, own_para_name
83 raise
84
86 """Collect the object attributes in the C{para} dictionary"""
87 self._collect_own_para()
88
90 """The same as L{set_own_para}. This method
91 is however tuned in the derived class L{Record}."""
92 self.set_own_para(para)
93
95 """Collect the object attributes in the C{para} dictionary.
96 For that object, just call C{collect_own_parameters} but this
97 method is tuned for many objects that need to call
98 C{collect_parameters} on some attributes"""
99 self.collect_own_parameters()
100
102 """Set the object attributes from the C{para} dictionary.
103 The same description as L{collect_parameters} can be applied, instead
104 that method is used for retrieving the object status."""
105 self.set_own_parameters(para)
106
107
109 """An object that is able to save
110 some of its attributes. Those results are saved
111 in the C{Results} instance, part of L{mbdyn.quantity},
112 and can be accessed by the C{res} or C{results}
113 attribute.
114 This class is always used as abstract, but the user
115 is invited to inherit from it if he wants to save
116 some attributes for its own object during the simulation.
117 """
118
120 RecordBase.__init__(self)
121
122 self.name = "Record"
123
124 self.results = Results()
125
126 self.res = self.results
127
128 self.saving_table = {}
129 self.saving_actions = {}
130 self.has_saving_actions = False
131
132
133
134
135
136 self.save_results = None
137
138 self.own_para_names += ["results"]
139
141 """Save no attributes during the simulation."""
142 self.results.names = []
143 self.results.clean()
144
146 """Add a new attribute to be saved during the simulation.
147 It will be executed in addition to the default ones or
148 to the ones already present."""
149 for arg in args:
150 if isinstance(arg, str):
151 self._try_to_add(arg)
152 else:
153 mess = "String are expected on the method will_save()"
154 print mess
155
157 """Try to add a new attribute to save
158 on the Results object."""
159 try:
160 getattr(self, attr_to_save)
161 self.results.add(attr_to_save)
162 except AttributeError:
163 mess = "Will not be able to save " + \
164 "the attribute '%s' " % attr_to_save + \
165 "on the object '%s' during the simulation." % self.name
166 print mess
167 return
168
170 """Only the quantities entered will be saved. The ones present
171 by default are lost."""
172 self.will_save_nothing()
173 self.will_save(*args)
174
176 """Initialize the results quantities, (erase the previous ones).
177 This method defined also """
178 self.results.init()
179 if self.has_saving_actions:
180 self.save_results = self._save_results_with_actions
181 else:
182 self.save_results = self._save_direct_results
183
185 """Initialize the results as in L{common_init_results}. This method
186 is however tuned in the derived classes"""
187 self.common_init_results()
188
190 """Perform the call of a method before saving the object
191 attribute"""
192 for attr_name, action in self.saving_actions.items():
193 setattr(self, attr_name, action())
194 for result_obj in self.results:
195 result_obj.append(getattr(self, result_obj.attr_name))
196
198 """Directly save the results by accessing to the object attribute."""
199 for result_obj in self.results:
200 result_obj.append(getattr(self, result_obj.attr_name))
201
203 """Save the results. This method is often tuned in
204 the derived objects for performing specific actions
205 when a new time step needs to be saved.
206 """
207 self.save_results()
208
210 """Set the object attributes from the C{para} dictionary."""
211 self.set_own_para(para)
212 self.res = self.results
213