File Writers

BlueSky callback that writes SPEC data files

SpecWriterCallback([filename, auto_write, …])

collect data from BlueSky RunEngine documents to write as SPEC data

spec_comment(comment[, doc, writer])

make it easy to add spec-style comments in a custom plan

EXAMPLE : the specfile_example() writes one or more scans to a SPEC data file using a jupyter notebook.

EXAMPLE : use as BlueSky callback:

from apstools.filewriters import SpecWriterCallback
specwriter = SpecWriterCallback()
RE.subscribe(specwriter.receiver)

EXAMPLE : use as writer from Databroker:

from apstools.filewriters import SpecWriterCallback
specwriter = SpecWriterCallback()
for key, doc in db.get_documents(db[-1]):
    specwriter.receiver(key, doc)
print("Look at SPEC data file: "+specwriter.spec_filename)

EXAMPLE : use as writer from Databroker with customizations:

from apstools.filewriters import SpecWriterCallback

# write into file: /tmp/cerium.spec
specwriter = SpecWriterCallback(filename="/tmp/cerium.spec")
for key, doc in db.get_documents(db[-1]):
    specwriter.receiver(key, doc)

# write into file: /tmp/barium.dat
specwriter.newfile("/tmp/barium.dat")
for key, doc in db.get_documents(db["b46b63d4"]):
    specwriter.receiver(key, doc)
class apstools.filewriters.SpecWriterCallback(filename=None, auto_write=True, RE=None, reset_scan_id=False)[source]

collect data from BlueSky RunEngine documents to write as SPEC data

This gathers data from all documents and appends scan to the file when the stop document is received.

Parameters

filenamestring, optional

Local, relative or absolute name of SPEC data file to be used. If filename=None, defaults to format of YYYmmdd-HHMMSS.dat derived from the current system time.

auto_writeboolean, optional

If True (default), write_scan() is called when stop document is received. If False, the caller is responsible for calling write_scan() before the next start document is received.

RE : instance of bluesky.RunEngine or None

reset_scan_idboolean, optional

If True, and filename exists, then sets RE.md.scan_id to highest scan number in existing SPEC data file. default: False

User Interface methods

receiver(key, document)

BlueSky callback: receive all documents for handling

newfile([filename, scan_id, RE])

prepare to use a new SPEC data file

usefile(filename)

read from existing SPEC data file

make_default_filename()

generate a file name to be used as default

clear()

reset all scan data defaults

prepare_scan_contents()

format the scan for a SPEC data file

write_scan()

write the most recent (completed) scan to the file

Internal methods

write_header()

write the header section of a SPEC data file

start(doc)

handle start documents

descriptor(doc)

handle descriptor documents

event(doc)

handle event documents

bulk_events(doc)

handle bulk_events documents

datum(doc)

handle datum documents

resource(doc)

handle resource documents

stop(doc)

handle stop documents

bulk_events(doc)[source]

handle bulk_events documents

clear()[source]

reset all scan data defaults

datum(doc)[source]

handle datum documents

descriptor(doc)[source]

handle descriptor documents

prepare for primary scan data, ignore any other data stream

event(doc)[source]

handle event documents

make_default_filename()[source]

generate a file name to be used as default

newfile(filename=None, scan_id=None, RE=None)[source]

prepare to use a new SPEC data file

but don’t create it until we have data

prepare_scan_contents()[source]

format the scan for a SPEC data file

Returns

[str] a list of lines to append to the data file

receiver(key, document)[source]

BlueSky callback: receive all documents for handling

resource(doc)[source]

handle resource documents

start(doc)[source]

handle start documents

stop(doc)[source]

handle stop documents

usefile(filename)[source]

read from existing SPEC data file

write_header()[source]

write the header section of a SPEC data file

write_scan()[source]

write the most recent (completed) scan to the file

  • creates file if not existing

  • writes header if needed

  • appends scan data

note: does nothing if there are no lines to be written

apstools.filewriters.spec_comment(comment, doc=None, writer=None)[source]

make it easy to add spec-style comments in a custom plan

These comments only go into the SPEC data file.

Parameters

commentstring, optional

Comment text to be written. SPEC expects it to be only one line!

docstring, optional (default: event)

Bluesky RunEngine document type. One of: start descriptor event resource datum stop

writerobj, optional

Instance of SpecWriterCallback(), typically: specwriter = SpecWriterCallback()

EXAMPLE:

Execution of this plan (with RE(myPlan())):

def myPlan():
    yield from bps.open_run()
    spec_comment("this is a start document comment", "start")
    spec_comment("this is a descriptor document comment", "descriptor")
    yield bps.Msg('checkpoint')
    yield from bps.trigger_and_read([scaler])
    spec_comment("this is an event document comment after the first read")
    yield from bps.sleep(2)
    yield bps.Msg('checkpoint')
    yield from bps.trigger_and_read([scaler])
    spec_comment("this is an event document comment after the second read")
    spec_comment("this is a stop document comment", "stop")
    yield from bps.close_run()

results in this SPEC file output:

#S 1145  myPlan()
#D Mon Jan 28 12:48:09 2019
#C Mon Jan 28 12:48:09 2019.  plan_type = generator
#C Mon Jan 28 12:48:09 2019.  uid = ef98648a-8e3a-4e7e-ac99-3290c9b5fca7
#C Mon Jan 28 12:48:09 2019.  this is a start document comment
#C Mon Jan 28 12:48:09 2019.  this is a descriptor document comment
#MD APSTOOLS_VERSION = 2019.0103.0+5.g0f4e8b2
#MD BLUESKY_VERSION = 1.4.1
#MD OPHYD_VERSION = 1.3.0
#MD SESSION_START = 2019-01-28 12:19:25.446836
#MD beamline_id = developer
#MD ipython_session_start = 2018-02-14 12:54:06.447450
#MD login_id = mintadmin@mint-vm
#MD pid = 21784
#MD proposal_id = None
#N 2
#L Epoch_float  scaler_time  Epoch
1.4297869205474854 1.1 1
4.596935987472534 1.1 5
#C Mon Jan 28 12:48:11 2019.  this is an event document comment after the first read
#C Mon Jan 28 12:48:14 2019.  this is an event document comment after the second read
#C Mon Jan 28 12:48:14 2019.  this is a stop document comment
#C Mon Jan 28 12:48:14 2019.  num_events_primary = 2
#C Mon Jan 28 12:48:14 2019.  exit_status = success

Example output from SpecWriterCallback():

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
#F test_specdata.txt
#E 1510948301
#D Fri Nov 17 13:51:41 2017
#C BlueSky  user = mintadmin  host = mint-vm

#S 233  scan(detectors=['synthetic_pseudovoigt'], num=20, motor=['m1'], start=-1.65, stop=-1.25, per_step=None)
#D Fri Nov 17 11:58:56 2017
#C Fri Nov 17 11:58:56 2017.  plan_type = generator
#C Fri Nov 17 11:58:56 2017.  uid = ddb81ac5-f3ee-4219-b047-c1196d08a5c1
#MD beamline_id = developer__YOUR_BEAMLINE_HERE
#MD login_id = mintadmin@mint-vm
#MD motors = ['m1']
#MD num_intervals = 19
#MD num_points = 20
#MD pid = 7133
#MD plan_pattern = linspace
#MD plan_pattern_args = {'start': -1.65, 'stop': -1.25, 'num': 20}
#MD plan_pattern_module = numpy
#MD proposal_id = None
#N 20
#L m1  m1_user_setpoint  Epoch_float  Epoch  synthetic_pseudovoigt
-1.6500000000000001 -1.65 8.27465009689331 8 2155.6249784809206
-1.6288 -1.6289473684210525 8.46523666381836 8 2629.5229081466964
-1.608 -1.6078947368421053 8.665581226348877 9 3277.4074328018964
-1.5868 -1.5868421052631578 8.865738153457642 9 4246.145049452576
-1.5656 -1.5657894736842104 9.066259145736694 9 5825.186516381953
-1.5448000000000002 -1.5447368421052632 9.266754627227783 9 8803.414029867528
-1.5236 -1.5236842105263158 9.467074871063232 9 15501.419687691103
-1.5028000000000001 -1.5026315789473683 9.667330741882324 10 29570.38936784884
-1.4816 -1.4815789473684209 9.867793798446655 10 55562.3437459487
-1.4604000000000001 -1.4605263157894737 10.067811012268066 10 89519.64275090238
-1.4396 -1.4394736842105262 10.268356084823608 10 97008.97190269837
-1.4184 -1.418421052631579 10.470621824264526 10 65917.29757650592
-1.3972 -1.3973684210526316 10.669955730438232 11 36203.46726798266
-1.3764 -1.3763157894736842 10.870310306549072 11 18897.64061096024
-1.3552 -1.3552631578947367 11.070487976074219 11 10316.223844200193
-1.3344 -1.3342105263157895 11.271018743515015 11 6540.179615556269
-1.3132000000000001 -1.313157894736842 11.4724280834198 11 4643.555421314616
-1.292 -1.2921052631578946 11.673305034637451 12 3533.8582404216445
-1.2712 -1.2710526315789474 11.874176025390625 12 2809.1872596809008
-1.25 -1.25 12.074703216552734 12 2285.9226305883626
#C Fri Nov 17 11:59:08 2017.  num_events_primary = 20
#C Fri Nov 17 11:59:08 2017.  time = 2017-11-17 11:59:08.324011
#C Fri Nov 17 11:59:08 2017.  exit_status = success