Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions deploy/packaging/debian/htsdevices.noarch
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
./usr/local/mdsplus/pydevices/HtsDevices/_version.py
./usr/local/mdsplus/pydevices/HtsDevices/acq2106_423st.py
./usr/local/mdsplus/pydevices/HtsDevices/acq2106_435sc.py
./usr/local/mdsplus/pydevices/HtsDevices/acq2106_423tr.py
./usr/local/mdsplus/pydevices/HtsDevices/acq2106_435st.py
./usr/local/mdsplus/pydevices/HtsDevices/acq2106_WRPG.py
./usr/local/mdsplus/pydevices/HtsDevices/acq2106_WRTD.py
Expand Down
1 change: 1 addition & 0 deletions deploy/packaging/redhat/htsdevices.noarch
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
./usr/local/mdsplus/pydevices/HtsDevices/_version.py
./usr/local/mdsplus/pydevices/HtsDevices/acq2106_423st.py
./usr/local/mdsplus/pydevices/HtsDevices/acq2106_435sc.py
./usr/local/mdsplus/pydevices/HtsDevices/acq2106_423tr.py
./usr/local/mdsplus/pydevices/HtsDevices/acq2106_435st.py
./usr/local/mdsplus/pydevices/HtsDevices/acq2106_WRPG.py
./usr/local/mdsplus/pydevices/HtsDevices/acq2106_WRTD.py
Expand Down
14 changes: 10 additions & 4 deletions pydevices/HtsDevices/acq2106_423st.py
Original file line number Diff line number Diff line change
Expand Up @@ -342,7 +342,7 @@ def run(self):
'wrtt1' # White Rabbit Trigger
]

def init(self):
def init(self, armed_by_transient = False):
uut = self.getUUT()
uut.s0.set_knob('set_abort', '1')

Expand Down Expand Up @@ -417,8 +417,13 @@ def init(self):
ch.COEFFICIENT.putData(float(coeffs[ic]))

self.running.on = True
thread = self.MDSWorker(self)
thread.start()

if not armed_by_transient:
# Then, the following will armed by this super-class
thread = self.MDSWorker(self)
thread.start()
else:
print('Skip streaming from MDSWorker thread. ACQ will be armed by the transient sub-class device')
INIT = init

def stop(self):
Expand Down Expand Up @@ -460,8 +465,9 @@ def assemble(cls):
'type': 'NUMERIC',
'options': ('no_write_model', 'write_once',)
},

{
'path': ':INPUT_%3.3d:OFFSET' % (i+1,),
'path': ':INPUT_%3.3d:OFFSET' % (i+1,),
'type': 'NUMERIC',
'options': ('no_write_model', 'write_once',)
},
Expand Down
296 changes: 296 additions & 0 deletions pydevices/HtsDevices/acq2106_423tr.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,296 @@
#!/usr/bin/env python
#
# Copyright (c) 2021, Massachusetts Institute of Technology All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
# Redistributions of source code must retain the above copyright notice, this
# list of conditions and the following disclaimer.
#
# Redistributions in binary form must reproduce the above copyright notice, this
# list of conditions and the following disclaimer in the documentation and/or
# other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
# DITRLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

import MDSplus
import threading
import importlib

acq2106_423st = importlib.import_module('acq2106_423st')

class _ACQ2106_423TR(acq2106_423st._ACQ2106_423ST):
"""
D-Tacq ACQ2106 Signal Conditioning support.
"""

tr_parts = [
# PRE and POST samples
{
'path':':PRESAMPLES','type':'numeric',
'value': int(1e5),
'options':('no_write_shot',)
},
{
'path':':POSTSAMPLES','type':'numeric',
'value': int(1e5),
'options':('no_write_shot',)
},
#Trigger sources
{
'path':':TRIG_SRC',
'type':'text',
'value': 'STRIG',
'options':('no_write_shot',)
},
#Event sources
{
'path':':EVENT0_SRC',
'type': 'text',
'value': 'EXT',
'options':('no_write_shot',)
},
]

def init(self):

# Here, the argument to the init of the superclass, i.e. the value True, means that the
# arming will be donw in this sub-class. In other words, cvalue True will not
# start a MDSWorker thread of the super-class, with the purpose of letting the sub-class
# to arm the digitazer:
# True ==> the transient recording will arm the digitazer.
super(_ACQ2106_423TR, self).init(armed_by_transient = True)

# Transient capture may be configured programmatically as follows, where
# PRE, POST are pre-trigger, post-trigger capture lengths in samples.
#
# transient [PRE=N] [POST=N] [OSAM=1] [SOFT_TRIGGER=1]
#
# Set trigger condition.
# With PRE=0:
# set.site 1 trg=1,0,1 - external TRG, rising
# set.site 1 event0=0,0,0 - no event
#
# With PRE > 0:
# set.site 1 trg=1,1,1 - local (SOFT) TRG
# set.site 1 event0=1,0,1 - external rising edge causes PRE - > POST
uut = self.getUUT()

uut.s0.transient = 'SOFT_TRIGGER=1' # Automatic

# If PRE samples different from zero
uut.s0.transient = "PRE={} POST={}".format(self.presamples.data(), self.postsamples.data())

print("{}".format(uut.s0.transient))

# Initializing Sources to NONE:
# D0 signal:
uut.s0.SIG_SRC_TRG_0 = 'NONE'
# D1 signal:
uut.s0.SIG_SRC_TRG_1 = 'NONE'

# Trigger sources choices:
# d0:
srcs_0 = ['EXT', 'HDMI', 'HOSTB', 'GPG0', 'DSP0', 'WRTT0', 'nc']
# d1:
srcs_1 = ['STRIG', 'HOSTA', 'HDMI_GPIO', 'GPG1', 'DSP1', 'FP_SYNC', 'WRTT1']

if str(self.trig_src.data()) in srcs_1:
uut.s0.SIG_SRC_TRG_1 = str(self.trig_src.data())
# Setting the signal (dX) to use for ACQ2106 stream control
uut.s1.TRG = 'enable'
uut.s1.TRG_DX = 'd1'
uut.s1.TRG_SENSE = 'rising'

# EVENT0 setting in d0:
if str(self.event0_src.data()) in srcs_0:
uut.s0.SIG_SRC_TRG_0 = str(self.event0_src.data())
uut.s1.EVENT0 = 'enable'
uut.s1.EVENT0_DX = 'd0'
uut.s1.EVENT0_SENSE = 'rising'
uut.s0.SIG_EVENT_SRC_0 = 'TRG' # In the EVENT bus, the source needs to be TRG to make the transition PRE->POST
else:
print("EVENT0 source should be one of {}, not {}".format(srcs_0, str(self.event0_src.data())))

elif str(self.trig_src.data()) in srcs_0:
uut.s0.SIG_SRC_TRG_0 = str(self.trig_src.data())
# Setting the signal (dX) to use for ACQ2106 stream control
uut.s1.TRG = 'enable'
uut.s1.TRG_DX = 'd0'
uut.s1.TRG_SENSE = 'rising'

# EVENT0 setting in d1:
if str(self.event0_src.data()) in srcs_1:
uut.s0.SIG_SRC_TRG_0 = str(self.event0_src.data())
uut.s1.EVENT0 = 'enable'
uut.s1.EVENT0_DX = 'd1'
uut.s1.EVENT0_SENSE = 'rising'
uut.s0.SIG_EVENT_SRC_0 = 'TRG' # In the EVENT bus, the source needs to be TRG to make the transition PRE->POST
else:
print("EVENT0 source should be one of {}".format(srcs_1))
else:
if self.debug:
print("TRG source was set to {}".format(str(self.trig_src.data())))

self.arm()

INIT=init


def arm(self):
import acq400_hapi
uut = acq400_hapi.Acq400(self.node.data())

shot_controller = acq400_hapi.ShotController([uut])
if self.debug:
print("Using HAPI ShotController to run the shot.")
shot_controller.run_shot()


def state(self):
import acq400_hapi
# State of the Transient recorder NOW (when this method was run)
uut = self.getUUT()

_status = [int(x) for x in uut.s0.state.split(" ")]

trstate = acq400_hapi.acq400.STATE.str(_status[0])

print("TR state: {}".format(trstate))
print("TR status: {}".format(_status))

STATE=state

def stop(self):
uut = self.getUUT()

print("{}".format(uut.s0.transient))
uut.s0.set_abort=1
self.running.on = False

STOP = stop

def store(self):
uut = self.getUUT()

while uut.statmon.get_state() != 0:
continue

self.chans = []
nchans = uut.nchan()

for ii in range(nchans):
self.chans.append(getattr(self, 'INPUT_%3.3d'%(ii+1)))

channel_data = uut.read_channels()

for ic, ch in enumerate(self.chans):
if ch.on:

start_idx = - self.presamples.data() + 1
end_idx = self.postsamples.data()

clock_period = 1./self.freq.data()

# When White Rabbit is used, we can get the trigger time from it:
# self.wr_wrtd_t0 is the reference to the node in the WRTD device. (secs)
# self.wr_wrtd_tai is the reference to the node in WRTD device. (TAI time)
# mdswindow = MDSplus.Window(start_idx, end_idx, self.wr_wrtd_t0)
# mdswindow = MDSplus.Window(start_idx, end_idx, self.wr_trig_tai)

mdswindow = MDSplus.Window(start_idx, end_idx, 0)
mdsrange = MDSplus.Range(None, None, clock_period)
dim = MDSplus.Dimension(mdswindow, mdsrange)

raw_signal = MDSplus.Signal(channel_data[ic], None, dim)
ch.RAW_INPUT.putData(raw_signal)

print("Storing data from all channels: done")
STORE=store

def getUUT(self):
import acq400_hapi
uut = acq400_hapi.Acq2106(self.node.data(), has_wr=True)
return uut

def assemble(cls):
cls.parts = list(_ACQ2106_423TR.carrier_parts + _ACQ2106_423TR.tr_parts)
for i in range(cls.sites*32):
cls.parts += [
{
'path': ':INPUT_%3.3d' % (i+1,),
'type': 'SIGNAL',
'valueExpr':
'ADD(MULTIPLY(head.INPUT_%3.3d.RAW_INPUT, head.INPUT_%3.3d.COEFFICIENT), head.INPUT_%3.3d.OFFSET)'
% (i+1,i+1,i+1),
'options': ('no_write_model','write_once',)
},

{
'path': ':INPUT_%3.3d:DECIMATE' % (i+1,),
'type': 'NUMERIC',
'valueExpr': 'head.def_decimate',
'options': ('no_write_shot',)
},

{
'path': ':INPUT_%3.3d:COEFFICIENT' % (i+1,),
'type': 'NUMERIC',
'options': ('no_write_model', 'write_once',)
},

{
'path': ':INPUT_%3.3d:OFFSET' % (i+1,),
'type': 'NUMERIC',
'options': ('no_write_model', 'write_once',)
},

{
'path': ':INPUT_%3.3d:RAW_INPUT' % (i+1,),
'type': 'SIGNAL',
'options': ('no_write_model','write_once',)
},
]


class ACQ2106_423TR_1ST(_ACQ2106_423TR):
sites=1

assemble(ACQ2106_423TR_1ST)

class ACQ2106_423TR_2ST(_ACQ2106_423TR):
sites=2

assemble(ACQ2106_423TR_2ST)

class ACQ2106_423TR_3ST(_ACQ2106_423TR):
sites=3

assemble(ACQ2106_423TR_3ST)

class ACQ2106_423TR_4ST(_ACQ2106_423TR):
sites=4

assemble(ACQ2106_423TR_4ST)

class ACQ2106_423TR_5ST(_ACQ2106_423TR):
sites=5

assemble(ACQ2106_423TR_5ST)

class ACQ2106_423TR_6ST(_ACQ2106_423TR):
sites=6

assemble(ACQ2106_423TR_6ST)

del(assemble)