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:
96
site_ansto/instrument/sans/config/commands/growfile.tcl
Normal file
96
site_ansto/instrument/sans/config/commands/growfile.tcl
Normal 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
|
@ -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
|
||||
|
||||
|
94
site_ansto/instrument/sans/util/dsc.py
Executable file
94
site_ansto/instrument/sans/util/dsc.py
Executable 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]
|
Reference in New Issue
Block a user