Log Data

The scan server allows for basic logging via the Log command. While not meant to provide complete data aquisition, it can be useful to track the progress of a scan or to perform basic measurements that won’t require a more sophisticated data aquisition.

Each time a device is logged by the Log command, this stores

Sample ID:

The first call to Log will use a sample ID of 0, the next call to Log will use a sample ID of 1 and so on. All samples logged with the same ID can thus be identified as having been logged by the same invocation of a Log command.

Time Stamp:

The time stamp in Posix milliseconds as reported by the device. Note that this it not the time when the sample was logged, but the current time stamp of the data reported by the device. To identify which samples where logged at the same time, use the sample ID.

Value:

The value is the current value of the device, either a number or a string.

from scan import *
  
client = ScanClient('localhost')

# Log data during scan
cmds = [ Loop('motor_x', 1, 10, 1,
              [ 
                  Set('neutrons', 0),
                  Loop('motor_y', 1, 3, 1,
                       [
                           Delay(1),
                           Log('motor_y')
                       ]),
                  Log('motor_x', 'neutrons')
              ])
       ]
id = client.submit(cmds, 'Data Demo')
print "Waiting for scan %d to finish..." % id
info = client.waitUntilDone(id)
print "Number of log calls: %d" % client.lastSerial(id)

# Direct access to data dict
data = client.getData(id)
print data
print "Values: ", data['motor_x']['value']
print "Times: ", data['motor_x']['time']

# Convert times from posix millisecs into local datatime
print "Times: ", [ str(getDatetime(time)) for time in  data['motor_x']['time'] ]

# Demo of sample iterator
for s in iterateSamples(data, 'motor_x'):
    print "%s (%2d): %s" % (str(getDatetime(s[1])), s[0], str(s[2]))
 
# Create table, i.e. align samples for different devices by sample ID:    
table = createTable(data, 'motor_x', 'neutrons')
print "Positions: ", table[0]
print "Counts   : ", table[1]
for (pos, count) in zip(*table):
    print "Counts at motor position %g: %g" % (pos, count)
    
# Could plot this with numpy/scipy:  plot(table[0], table[1]) etc.

Example

API

scan.client.logdata.getDatetime(time)

Convert log time

Parameters

time – Posix millisecond timestamp of logged sample

Returns

datetime

scan.client.logdata.iterateSamples(data, device)

Sample iterator

Iterator over samples of one device. At each step of the iteration, it provides a logged sample as a tuple containing

  1. Sample id

  2. Time stamp in Posix milliseconds

  3. Value, which is a number or a string

Parameters
  • data – Data as returned by getData()

  • device – Device for which to iterate over samples

Returns

Generator for the samples of the device as tuples ( id, time, value )

scan.client.logdata.iterateTable(*iters)

Iterate data for several devices by sample ID

While iterating over the samples from basic per-channel iterators, their values are aligned by sample ID. Each iteration returns a ‘row’ in a table where all samples on that row have either the same sample ID, or a previous sample ID in case there was no new data available and the previous value still applies.

Parameters

iters – Iterators for the samples of desired channels

Returns

Generator for rows of a table. Each invocation of the generator return [ value[0], value[1], …] where value[0] is the value of the first device, value[1] for second device and so on.

scan.client.logdata.createTable(data, *devices)

Create data table

Aligns samples for given list of devices by sample ID.

Parameters
  • data – Data as returned by getData()

  • devices – One or more devices

Returns

Table. result[0] has values for first device, result[1] for second device and so on.