1 from readers
.detect_reader
import DetectReader
2 from readers
.reader
import ReadError
3 from writers
.detect_writer
import DetectWriter
4 from writers
.writer
import WriteError
5 from figure
import Figure
8 class Context(gobject
.GObject
):
9 """ Class Context -- Interface between signals, files and figures
11 This object is the interface between the signals, the files and the figures.
12 It gathers operations on figures, signals, readers and writers and thus
13 can be used for a program such ioscopy.
14 It maintain a list of figures, a dict of reader and a dict of signals.
16 Signals are stored in a dict according to their user name (Signal.name)
17 Files are stored in a dict according to their name
20 signals read/write Dict of Signals read
21 readers read/write Dict of Readers used
22 figures read/write Dict of Figures instanciated
25 'begin-transaction' is received to notify that Dependancy Signal data is
26 being changed. Event re-emitted toward Listeners
27 'end-transaction' is emitted once the Result Signal data is recomputed
28 to notify Listeners that they can recompute their own data
37 'begin-transaction': (gobject
.SIGNAL_RUN_LAST
, gobject
.TYPE_NONE
, ()),
38 'end-transaction': (gobject
.SIGNAL_RUN_LAST
, gobject
.TYPE_NONE
, ())
42 """ Create the instance variables
52 gobject
.GObject
.__init
__(self
)
57 self
._signal
_name
_to
_reader
= {}
59 def create(self
, sigs
):
60 """ Instanciate a new figure
61 No error reported if parameter type mismatches, silently does nothing
65 sigs: string or list of signals
66 Contains the list of signals for the Figure instanciation
67 See also Figure.Figure()
73 if isinstance(sigs
, list):
74 # Called from commandline,
75 # Get the signal list from args
77 sigs
= self
.names_to_signals(sigs
)
79 # No signal list provided
81 elif not isinstance(sigs
, dict):
84 self
._figures
.append(f
)
86 def destroy(self
, num
):
88 If num is out of range issue an assertion.
89 Figure is replaced by None in the list to keep code simple
94 The number of the figure to destroy
100 if num
> len(self
._figures
) or num
< 1:
101 assert 0, _("Out of range figure number")
102 self
._figures
[num
- 1] = None
105 """ Read signals from file
106 Overwrite signals in case of Signal name conflict.
107 On success, Reader and Signals are added in the lists.
116 sigs: Dict of Signals
117 List of Signals read from the file
122 Do not read the same file twice
125 When the file type is not managed by any Reader
127 # File already loaded ?
128 if fn
in self
._readers
.keys():
129 raise _("File already loaded, use update to read it again")
133 raise NotImplementedError()
135 self
.connect('begin-transaction', r
.on_begin_transaction
)
136 self
.connect('end-transaction', r
.on_end_transaction
)
138 # Insert signals into the dict
139 for sn
in sigs
.keys():
140 self
._signals
[sn
] = sigs
[sn
]
141 self
._signal
_name
_to
_reader
[sn
] = r
142 self
._readers
[fn
] = r
145 def write(self
, fn
, fmt
, sns
, opts
):
146 """ Write signals to file
157 The Signals to record
160 List of options to pass to the Writer
169 When the file type is not managed by any Writer
172 sigs
= self
.names_to_signals(sns
)
175 w
= DetectWriter(fmt
, fn
, True)
177 w
.write(fn
, sigs
, opts
)
179 raise NotImplementedError()
181 def update(self
, r
=None, upn
=-1):
182 """ Reread signal from files.
183 For each file, reread it, and for updated, new and deleted signal,
184 update the Signal dict accordingly.
187 Note: recursion is now deprecated by using GObject event system by
188 Signals, it will be removed in a future release
193 Update Signals from this Reader only
196 Reserved for internal use (recursion) should always be the default value
201 """ ## SUPPORT FOR UPDATE SINGLE READER
204 self
.emit('begin-transaction')
205 # Normal call create the new list etc etc
206 self
._update
_num
+= 1
208 for reader
in self
._readers
.itervalues():
209 # print "Updating signals from", reader
210 n
.update(self
.update(reader
, self
._update
_num
))
212 n
.update(self
.update(r
, self
._update
_num
))
213 self
.emit('end-transaction')
215 # First look at its dependencies
216 if hasattr(r
, "get_depends") and callable(r
.get_depends
):
217 for sn
in r
.get_depends():
218 # print " Updating signals from", self._signal_name_to_reader[sn]
219 n
.update(self
.update(self
._signal
_name
_to
_reader
[sn
], self
._update
_num
))
220 # TODO: Update depencies: what happens to vo when
221 # vout is deleted ? It seems it is not deleted: it should!
223 n
.update(r
.update(self
._update
_num
, keep
=False))
226 # Find deleted signals
228 for sn
, s
in self
._signals
.iteritems():
229 #n.update(s.update(self._update_num, False))
233 self
._signals
.update(n
)
234 # Delete signals from all graphs of all figures
235 for f
in self
._figures
:
237 g
.remove(self
.names_to_signals(d
))
239 if f
.canvas
is not None:
242 del self
._signals
[sn
]
244 def freeze(self
, sns
):
245 """ Set the freeze flag of signals, i.e. disable updates
250 Signals list to be frozen
256 sigs
= self
.names_to_signals(sns
)
257 for s
in sigs
.itervalues():
260 def unfreeze(self
, sns
):
261 """ Unset the freeze flag of signals, i.e. enable updates
266 Signals list to be unfrozen
272 sigs
= self
.names_to_signals(sns
)
273 for s
in sigs
.itervalues():
278 """ Dict of loaded signals
287 List of Signals currently loaded in this Context
291 def import_signal(self
, sig
, name
):
292 """ Import a signal from outside this Context
297 Signal to be imported
300 Name to be assigned to the Signal in this Context
305 Contains only one element, the Signal imported
309 >>> ctxt=oscopy.Context()
310 >>> ctxt.read('demo/tran.dat')
312 >>> v1=oscopy.Signal('v1', 'V')
313 >>> ctxt.import_signal(v1, 'v1imported')
316 r
= DetectReader(sig
)
317 ss
= r
.read((sig
, name
))
318 for sn
, s
in ss
.iteritems():
319 self
._signals
[sn
] = s
320 self
._signal
_name
_to
_reader
[sn
] = r
321 # FIXME: Probleme, comment gerer les dependances ?
323 rname
= "%s=%s" % (name
, sig
.name
)
324 self
.readers
[rname
] = r
327 def names_to_signals(self
, sns
):
328 """ Return a signal dict from the signal names list provided
329 If no signals are found, return {}
330 Use this function is reserved, will be made private in a future release
335 The list of name of Signals to retrieve
339 sigs: dict of Signals
340 The list of Signals found in this Context
342 if not sns
or not self
._signals
:
346 # Prepare the signal list
348 if sn
in self
._signals
.keys():
349 sigs
[sn
] = self
._signals
[sn
]
351 # print sn + ": Not here"
356 # print "No signals found"
361 """ Return the figure list
369 List of Figures managed in this Context
375 """ Return the reader list
383 List of Readers managed in this Context