Package mbdyn :: Module record
[hide private]

Source Code for Module mbdyn.record

  1  #!/usr/bin/env python 
  2  # -*- coding: utf-8 -*- 
  3  # 
  4  # This file is part of MBDyn sim suite. 
  5  # Copyright (C) 2007 André ESPAZE, as part of a Master thesis supervised by 
  6  # Martin O.L.Hansen (DTU) and Nicolas Chauvat (Logilab) 
  7   
  8  # MBDyn sim suite is free software; you can redistribute it and/or modify 
  9  # it under the terms of the GNU General Public License as published by 
 10  # the Free Software Foundation; either version 2 of the License, or 
 11  # (at your option) any later version. 
 12  # 
 13  # This program is distributed in the hope that it will be useful, 
 14  # but WITHOUT ANY WARRANTY; without even the implied warranty of 
 15  # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
 16  # GNU General Public License for more details. 
 17  # 
 18  # You should have received a copy of the GNU General Public License 
 19  # along with this program; if not, write to the Free Software 
 20  # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 
 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   
31 -class ParametersToSave(DictType):
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
39 -class RecordBase:
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
49 - def __init__(self):
50 self.para = ParametersToSave() 51 self.own_para_names = []
52
53 - def _collect_own_para(self):
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
64 - def set_own_para(self, para):
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
85 - def collect_own_parameters(self):
86 """Collect the object attributes in the C{para} dictionary""" 87 self._collect_own_para()
88
89 - def set_own_parameters(self, para):
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
94 - def collect_parameters(self):
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
101 - def set_parameters(self, para):
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
108 -class Record(RecordBase):
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
119 - def __init__(self):
120 RecordBase.__init__(self) 121 # This attribute will be overwritten by derived class 122 self.name = "Record" 123 124 self.results = Results() 125 # To make the interaction easier 126 self.res = self.results 127 128 self.saving_table = {} 129 self.saving_actions = {} 130 self.has_saving_actions = False 131 132 # This method will point whether 133 # to '_save_results_with_actions' or '_save_direct_results'. 134 # It will be chosen during the initialization of results in 135 # 'init_results'. 136 self.save_results = None 137 138 self.own_para_names += ["results"]
139
140 - def will_save_nothing(self):
141 """Save no attributes during the simulation.""" 142 self.results.names = [] 143 self.results.clean()
144
145 - def will_save(self, *args):
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
156 - def _try_to_add(self, attr_to_save):
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
169 - def will_save_only(self, *args):
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
175 - def common_init_results(self):
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
184 - def init_results(self):
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
197 - def _save_direct_results(self):
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
202 - def save(self):
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
209 - def set_own_parameters(self, para):
210 """Set the object attributes from the C{para} dictionary.""" 211 self.set_own_para(para) 212 self.res = self.results
213