Groups of scans¶
Bliss provides the capability to bundle several scans together into a sequence.
Scan sequences¶
Sequences can be used to group together multiple scans to be run during this sequence. Sub scans have to be added to the sequence before running it. And at the end of the sequence the whole sub scans will be terminated.
The ScanSequence
object takes commons keyword arguments like title
or scan_info
.
It’s a normal scan which can be monitored with blissdata
.`
Example
TEST_SESSION [4]: from bliss.scanning.scan_sequence import ScanSequence
...: def runner(scan_seq):
...: s1 = loopscan(5, .1, diode, run=False)
...: scan_seq.add(s1)
...: s1.run()
...:
...: # do something here ... move motors, open/close shutter
...:
...: s2 = loopscan(3, .2, diode, run=False)
...: scan_seq.add_and_run(s2)
...:
...: # do more things
...:
...: s3 = loopscan(3,.2,diode, run=False)
...: scan_seq.add_and_run(s3)
...:
...: scan = ScanSequence(runner=runner)
...: scan.run()
In the example above we create a function which handle a set of scans
(s1 and s2 … note the run=False
keyword argument) and add them to the
sequence by calling add_and_run
(or add
to handle the run manually).
Channels attached to sequences¶
It is possible to publish additional channels that are not part of any of the scans inside the sequence. These channels could e.g. be the result of a calculation based on the data acquired during the sequence.
Example
TEST_SESSION [12]: from bliss.scanning.scan_sequence import ScanSequence
...: from bliss.scanning.chain import AcquisitionChannel
...: import numpy
...: ch1 = AcquisitionChannel("mychannel", float, ())
...: ch2 = AcquisitionChannel("sum", float, ())
...: def runner(scan_seq):
...: s1=loopscan(5, .1, diode, run=False)
...: s2=loopscan(5, .1, diode, run=False)
...: scan_seq.add_and_run(s1)
...: scan_seq.add_and_run(s2)
...:
...: scan_seq.emit('mychannel', [1.1, 2.2, 3.3])
...:
...: my_sum = s1.get_data()[diode] + s2.get_data()[diode]
...: scan_seq.emit("sum", my_sum)
...: scan = ScanSequence(runner=runner, channels=[ch1, ch2])
In the example above we create a function which handle a set of scans (s1 and s2). We can retreive data from this scans and emit this values to the channels linked to the scan sequence
Sequences (deprecated)¶
This example still work but should be replaced by ScanSequence
(see above)
Sequences can be used to bundle scans no matter if they have already been
executed before or if they will be running during the sequence. The only
condition: all scans of the sequence must terminate before leaving the context
manager provided by the sequence. The Sequences
object takes as keyword
arguments title
and scan_info
.
Example
TEST_SESSION [4]: from bliss.scanning.group import Sequence
...: seq=Sequence()
...: with seq.sequence_context() as scan_seq:
...: s1=loopscan(5,.1,diode,run=False)
...: scan_seq.add(s1)
...: s1.run()
...:
...: #do something here ... move motors, open/close shutter
...:
...: s2=loopscan(3,.2,diode,run=False)
...: scan_seq.add_and_run(s2)
...:
...: #do more things
...:
...: s3=loopscan(3,.2,diode)
...: scan_seq.add(s3)
In the example above we prepare scans (s1 and s2 … note the run=False
keyword argument) and add them to the sequence by calling add
or add_and_run
.
It is also possible to add a scan that has already terminated (s3). However, when
thinking about online data analysis it is advisable to first add the scans to the
sequences and run them afterwards (like s1 and s2) as this enables external
processes to follow the sequence in real time.
Channels attached to sequences¶
It is possible to publish additional channels that are not part of any of the scans inside the sequence. These channels could e.g. be the result of a calculation based on the data acquired during the sequence.
Example
TEST_SESSION [12]: from bliss.scanning.group import Sequence
...: from bliss.scanning.chain import AcquisitionChannel
...: import numpy
...: seq=Sequence()
...: seq.add_custom_channel(AcquisitionChannel('mychannel',float,()))
...: seq.add_custom_channel(AcquisitionChannel('sum',float,()))
...: with seq.sequence_context() as scan_seq:
...: s1=loopscan(5,.1,diode,run=False)
...: s2=loopscan(5,.1,diode,run=False)
...: scan_seq.add_and_run(s1)
...: scan_seq.add_and_run(s2)
...:
...: seq.custom_channels['mychannel'].emit([1.1,2.2,3.3])
...:
...: my_sum = s1.get_data()[diode] + s2.get_data()[diode]
...: seq.custom_channels['sum'].emit(my_sum)