SICS-458: Add dsc command to run a DSC acquisition on Quokka.

Also added dsc.py utility which finds the start of a DSC profile in hdf files.
This commit is contained in:
Ferdi Franceschini
2014-08-21 10:19:55 +10:00
parent 6054eeeae9
commit a0acd1e5b4
3 changed files with 191 additions and 0 deletions

View File

@ -0,0 +1,96 @@
# \file Implements 'dsc actime interval' command.
set GROWFILE_STATE "DISABLED"
set growfileSaveIndex 0
proc doGrowFile {} {
global GROWFILE_STATE
global growfileSaveIndex
# Reset the GROWFILE_STATE variable in case some naughty user sets it directly
set GROWFILE_STATE "ENABLED"
set HMSTATE [SplitReply [hmm configure daq]]
set FSTATE [SplitReply [file_status]]
# broadcast CALLED: [info level 0], HMSTATE = $HMSTATE, FSTATE = $FSTATE
if { $FSTATE != "UNKNOWN" && $FSTATE != "OPEN" && $HMSTATE == "Started"} {
# broadcast growfile $growfileSaveIndex
save $growfileSaveIndex "growfile"
incr growfileSaveIndex
} else {
if {$growfileSaveIndex == 0} {
broadcast ERROR: GROWFILE HMSTATE = $HMSTATE, FSTATE = $FSTATE. The histmem must be running and you must create a newfile before calling "growfile"
} else {
broadcast STOP GROWFILE Acquisition finished. HMSTATE = $HMSTATE, FSTATE = $FSTATE.
save $growfileSaveIndex "growfile"
newfile clear
broadcast Saved [hval /experiment/file_name]
}
set growfileSaveIndex 0
sicspoll del doGrowFile
set GROWFILE_STATE "DISABLED"
hsetprop /instrument/detector/hmm mutable true
}
}
publish doGrowFile user
proc growfile { {interval 300} } {
global GROWFILE_STATE
global growfileSaveIndex
set GROWFILE_STATE "DISABLED"
set growfileSaveIndex 0
set as_error 0
set myrights [set_rights manager]
if {$myrights == -1} {
return -code error "ERROR: You are not authorized for this operation"
}
set interval [string tolower $interval]
if {$interval == "check" || $interval == "status"} {
if { $GROWFILE_STATE == "ENABLED" } {
return "GROWFILE $GROWFILE_STATE [sicspoll intervall doGrowFile]"
} else {
return "GROWFILE $GROWFILE_STATE"
}
} elseif {[string is integer $interval]} {
if {$interval <= 0} {
if { $GROWFILE_STATE == "ENABLED" } {
sicspoll del doGrowFile
set GROWFILE_STATE "DISABLED"
}
} else {
if {$GROWFILE_STATE == "DISABLED"} {
sicspoll add doGrowFile script $interval doGrowFile
# sicspoll listen # WARNING:When the listening client exits it leaves SICSPOLL task with a corrupt connection object.
set GROWFILE_STATE "ENABLED"
} else {
sicspoll intervall doGrowFile $interval
}
}
} else {
set as_error 1
}
set_rights $myrights
if {$as_error} {
return -code error "ERROR: Invalid argument in '[info level 0]', should be an integer or 'check'"
}
}
publish growfile user
# \brief Run histogram for the specified time and save XY binned data at the given interval.
# \param actime Acquisition time in seconds.
# \param saveint Save interval in seconds.
proc dsc {actime saveint} {
hsetprop /instrument/detector/hmm mutable false
newfile HISTOGRAM_XY
histmem mode time
histmem preset $actime
histmem start
growfile $saveint
}
publish dsc user

View File

@ -73,6 +73,7 @@ fileeval $cfPath(environment)/sct_antonparr_MCR500.tcl
fileeval $cfPath(beamline)/spin_flipper.tcl
fileeval $cfPath(commands)/pulser.tcl
fileeval $cfPath(commands)/hvcommands.tcl
fileeval $cfPath(commands)/growfile.tcl
source gumxml.tcl

View File

@ -0,0 +1,94 @@
#!/usr/bin/env python
# vim: ft=python ts=8 sts=4 sw=4 expandtab autoindent smartindent
""" Find the trigger time for Differenctial Scanning Calorimetry data in nx.hdf files. """
import sys
import os
import h5py
import argparse
import time
from collections import defaultdict
class SkipFile(BaseException):
"""This exception should be raised to skip processing a file"""
pass
PARSER = argparse.ArgumentParser(
description = """Report the time offset for the start of the DSC profile relative to the start time of the histogram data.
This program can process multiple hdf files by specifying the path to the first file and the number of files to process.
You can also speficy a list of 'file_path numfile' pairs.""",
usage='dsc file_path numfile {file_path numfile}'
)
PARSER.add_argument('files', nargs='+', help = 'List of "file_path numfile" pairs')
ARGS = PARSER.parse_args()
FAILS = defaultdict(list)
for startfile, num in zip(ARGS.files[0::2], ARGS.files[1::2]):
numfiles = int(num)
hfdir = os.path.dirname(startfile)
hfbase = os.path.basename(startfile)
idx = hfbase.find('.')
startFID = hfbase[:idx]
ext = hfbase[idx:]
idnum = int(startFID[3:])
inst_abname = hfbase[:3]
hfval = {}
print
for i in range(numfiles):
try:
currid = idnum + i
fileID = inst_abname + '%07d' % currid
if (hfdir == ''):
nxfile = fileID + ext
else:
nxfile = hfdir + '/' + fileID + ext
try:
hf = h5py.File(nxfile, 'r')
except:
FAILS['badfile'].append(nxfile)
continue
if (hfbase.startswith('QKK')):
rootpath = fileID + '/'
else:
rootpath = 'entry1/'
for dpath in ['time_stamp', 'instrument/detector/start_time', 'sample/dsc_val']:
dscpath = rootpath + dpath
if dscpath in hf:
hfval[dpath] = hf[dscpath][:]
else:
FAILS['badpath:{0}'.format(dpath)].append(nxfile)
hf.close()
raise SkipFile
print fileID
datiter = {}
dat_hasnext = 0
time_tuple = time.strptime(hf[rootpath + 'start_time'][0], '%Y-%m-%d %H:%M:%S')
hfval['time_stamp'] += time.mktime(time_tuple)
hfval['time_stamp'] -= hfval['instrument/detector/start_time']
dsc0 = hfval['sample/dsc_val'][0]
no_transition = True
for i in range(1, len(hfval['sample/dsc_val'][1:])):
dsc1 = hfval['sample/dsc_val'][i]
if abs(dsc1 - dsc0) > 1.9:
no_transition = False
msg = 'dsc_val transition from {dsc0} to {dsc1} volts at {time} seconds from detector start time, array index = {index}'
print msg.format(dsc0=dsc0, dsc1=dsc1, time=hfval['time_stamp'][i], index=i)
dsc0 = dsc1
if no_transition:
print 'dsc_val no transition'
print
hf.close()
except SkipFile:
continue
for k in FAILS.keys():
if (len(FAILS[k])):
print >> sys.stderr, 'Skipped following files. Reason = ', k
print >> sys.stderr, FAILS[k]