Added MIRNOV Signals

Signed-off-by: Bernardo Carvalho <bernardo.carvalho@tecnico.ulisboa.pt>
This commit is contained in:
2025-05-19 17:17:53 +01:00
parent 07e55edd33
commit 5a50d1920e
2 changed files with 417 additions and 0 deletions

264
Trees/CreateIsttokMARTe.tcl Normal file
View File

@@ -0,0 +1,264 @@
edit isttokmarte/new
add node .INP
add node .REFS
add node .ERRORS
add node .CONTROLS
add node .STATES
add node .PERF
add node TIME/usage=signal
add node TIMED/usage=signal
add node .DIAGNOSTICS
add node .HARDWARE
set def .HARDWARE
add node .ATCA_1
add node .ATCA_2
# set def \ISTTOKSDAS::TOP.HARDWARE.ATCA1
set def .ATCA_1
add node IOC_0/model=IOCMIMORT
add node IOC_1/model=IOCMIMORT
set def \ISTTOKMARTE::TOP.HARDWARE.ATCA_1.IOC_1"
put SLOT "2"
# put CLOCK_FREQ "20000"
set def \ISTTOKMARTE::TOP.HARDWARE.ATCA_2"
add node IOP_9/model=ATCA_IOP
set def \ISTTOKMARTE::TOP.HARDWARE.ATCA_2.IOP_9"
put RT_DECIM "200"
put SLOT "9"
set def \isttokmarte::top.hardware.atca_2.iop_9.channel_0
# calibration on 14/05/2025
put gain "1.73887463e-05"
put inp_decim "gain * adc_decim"
put inp_integ "gain * adc_integ / \isttokmarte::top.hardware.atca_2.iop_9.rt_decim / \isttokmarte::top.hardware.atca_2.iop_9.clock_freq"
set def \isttokmarte::top.hardware.atca_2.iop_9.channel_1
put gain "1.73937683e-05"
put inp_decim "gain * adc_decim"
put inp_integ "gain * adc_integ / \isttokmarte::top.hardware.atca_2.iop_9.rt_decim / \isttokmarte::top.hardware.atca_2.iop_9.clock_freq"
set def \isttokmarte::top.hardware.atca_2.iop_9.channel_2
put gain "1.74275762e-05"
put inp_decim "gain * adc_decim"
put inp_integ "gain * adc_integ / \isttokmarte::top.hardware.atca_2.iop_9.rt_decim / \isttokmarte::top.hardware.atca_2.iop_9.clock_freq"
set def \isttokmarte::top.hardware.atca_2.iop_9.channel_3
put gain "1.74994244e-05"
put inp_decim "gain * adc_decim"
put inp_integ "gain * adc_integ / \isttokmarte::top.hardware.atca_2.iop_9.rt_decim / \isttokmarte::top.hardware.atca_2.iop_9.clock_freq"
set def \isttokmarte::top.hardware.atca_2.iop_9.channel_4
put gain "1.73826859e-05"
put inp_decim "gain * adc_decim"
put inp_integ "gain * adc_integ / \isttokmarte::top.hardware.atca_2.iop_9.rt_decim / \isttokmarte::top.hardware.atca_2.iop_9.clock_freq"
set def \isttokmarte::top.hardware.atca_2.iop_9.channel_5
put gain "1.74439575e-05"
put inp_decim "gain * adc_decim"
put inp_integ "gain * adc_integ / \isttokmarte::top.hardware.atca_2.iop_9.rt_decim / \isttokmarte::top.hardware.atca_2.iop_9.clock_freq"
set def \isttokmarte::top.hardware.atca_2.iop_9.channel_6
put gain "1.74532093e-05"
put inp_decim "gain * adc_decim"
put inp_integ "gain * adc_integ / \isttokmarte::top.hardware.atca_2.iop_9.rt_decim / \isttokmarte::top.hardware.atca_2.iop_9.clock_freq"
set def \isttokmarte::top.hardware.atca_2.iop_9.channel_7
put gain "1.73723740e-05"
put inp_decim "gain * adc_decim"
put inp_integ "gain * adc_integ / \isttokmarte::top.hardware.atca_2.iop_9.rt_decim / \isttokmarte::top.hardware.atca_2.iop_9.clock_freq"
set def \isttokmarte::top.hardware.atca_2.iop_9.channel_8
put gain "1.71925327e-05"
put inp_decim "gain * adc_decim"
put inp_integ "gain * adc_integ / \isttokmarte::top.hardware.atca_2.iop_9.rt_decim / \isttokmarte::top.hardware.atca_2.iop_9.clock_freq"
set def \isttokmarte::top.hardware.atca_2.iop_9.channel_9
put gain "1.72739424e-05"
put inp_decim "gain * adc_decim"
put inp_integ "gain * adc_integ / \isttokmarte::top.hardware.atca_2.iop_9.rt_decim / \isttokmarte::top.hardware.atca_2.iop_9.clock_freq"
set def \isttokmarte::top.hardware.atca_2.iop_9.channel_10
put gain "1.73809822e-05"
put inp_decim "gain * adc_decim"
put inp_integ "gain * adc_integ / \isttokmarte::top.hardware.atca_2.iop_9.rt_decim / \isttokmarte::top.hardware.atca_2.iop_9.clock_freq"
set def \isttokmarte::top.hardware.atca_2.iop_9.channel_11
put gain "1.74412886e-05"
put inp_decim "gain * adc_decim"
put inp_integ "gain * adc_integ / \isttokmarte::top.hardware.atca_2.iop_9.rt_decim / \isttokmarte::top.hardware.atca_2.iop_9.clock_freq"
#set def \ISTTOKMARTE::TOP.INP
#add node MEAS0/usage=signal
#add node MEAS0D/usage=signal
#add node MEAS0F/usage=signal
#add node MEAS0FD/usage=signal
#add node MEAS1/usage=signal
#add node MEAS1D/usage=signal
#add node MEAS1F/usage=signal
#add node MEAS1FD/usage=signal
set def \ISTTOKMARTE::TOP.REFS
add node REF0/usage=signal
add node REF0D/usage=signal
add node REF1/usage=signal
add node REF1D/usage=signal
set def \ISTTOKMARTE::TOP.ERRORS
add node ERROR0/usage=signal
add node ERROR0D/usage=signal
add node ERROR1/usage=signal
add node ERROR1D/usage=signal
set def \ISTTOKMARTE::TOP.CONTROLS
add node CONTROL0/usage=signal
add node CONTROL0D/usage=signal
add node CONTROL1/usage=signal
add node CONTROL1D/usage=signal
set def \ISTTOKMARTE::TOP.STATES
add node STATE0/usage=signal
add node STATE0D/usage=signal
add node STATE1/usage=signal
add node STATE1D/usage=signal
add node STATE2/usage=signal
add node STATE2D/usage=signal
add node STATE3/usage=signal
add node STATE3D/usage=signal
set def \ISTTOKMARTE::TOP.PERF
add node CYCLET/usage=signal
add node CYCLETD/usage=signal
set def \ISTTOKMARTE::TOP.DIAGNOSTICS
add node MAGNETICS
set def .MAGNETICS
add node .MIRNOV
set def .MIRNOV
add node PROBE1
add node PROBE2
add node PROBE3
add node PROBE4
add node PROBE5
add node PROBE6
add node PROBE7
add node PROBE8
add node PROBE9
add node PROBE10
add node PROBE11
add node PROBE12
set def \ISTTOKMARTE::TOP.DIAGNOSTICS.MAGNETICS.MIRNOV.PROBE1
add node ANGLE/usage=numeric
put ANGLE "15.1"
add node AREA/usage=numeric
# Total area: turns * A : 0.0049**2 * 50
put AREA "0.0012005"
add node POL/usage=numeric
put POL "-1"
add node SIG/usage=signal
put SIG "POL * \ISTTOKMARTE::TOP.HARDWARE.ATCA_2.IOP_9.CHANNEL_0.INP_INTEG"
set def \ISTTOKMARTE::TOP.DIAGNOSTICS.MAGNETICS.MIRNOV.PROBE2
add node ANGLE/usage=numeric
put ANGLE "30.2"
add node AREA/usage=numeric
put AREA "0.0012005"
add node POL/usage=numeric
put POL "-1"
add node SIG/usage=signal
put SIG "POL * \ISTTOKMARTE::TOP.HARDWARE.ATCA_2.IOP_9.CHANNEL_1.INP_INTEG"
set def \ISTTOKMARTE::TOP.DIAGNOSTICS.MAGNETICS.MIRNOV.PROBE3
add node ANGLE/usage=numeric
put ANGLE "30.2"
add node AREA/usage=numeric
put AREA "0.0012005"
add node POL/usage=numeric
put POL "1"
add node SIG/usage=signal
put SIG "POL * \ISTTOKMARTE::TOP.HARDWARE.ATCA_2.IOP_9.CHANNEL_2.INP_INTEG"
set def \ISTTOKMARTE::TOP.DIAGNOSTICS.MAGNETICS.MIRNOV.PROBE4
add node ANGLE/usage=numeric
put ANGLE "30.2"
add node AREA/usage=numeric
put AREA "0.0012005"
add node POL/usage=numeric
put POL "-1"
add node SIG/usage=signal
put SIG "POL * \ISTTOKMARTE::TOP.HARDWARE.ATCA_2.IOP_9.CHANNEL_3.INP_INTEG"
set def \ISTTOKMARTE::TOP.DIAGNOSTICS.MAGNETICS.MIRNOV.PROBE5
add node ANGLE/usage=numeric
put ANGLE "30.2"
add node AREA/usage=numeric
put AREA "0.0012005"
add node POL/usage=numeric
put POL "1"
add node SIG/usage=signal
put SIG "POL * \ISTTOKMARTE::TOP.HARDWARE.ATCA_2.IOP_9.CHANNEL_4.INP_INTEG"
set def \ISTTOKMARTE::TOP.DIAGNOSTICS.MAGNETICS.MIRNOV.PROBE6
add node ANGLE/usage=numeric
put ANGLE "30.2"
add node AREA/usage=numeric
put AREA "0.0012005"
add node POL/usage=numeric
put POL "1"
add node SIG/usage=signal
put SIG "POL * \ISTTOKMARTE::TOP.HARDWARE.ATCA_2.IOP_9.CHANNEL_5.INP_INTEG"
set def \ISTTOKMARTE::TOP.DIAGNOSTICS.MAGNETICS.MIRNOV.PROBE7
add node ANGLE/usage=numeric
put ANGLE "30.2"
add node AREA/usage=numeric
put AREA "0.0012005"
add node POL/usage=numeric
put POL "1"
add node SIG/usage=signal
put SIG "POL * \ISTTOKMARTE::TOP.HARDWARE.ATCA_2.IOP_9.CHANNEL_6.INP_INTEG"
set def \ISTTOKMARTE::TOP.DIAGNOSTICS.MAGNETICS.MIRNOV.PROBE8
add node ANGLE/usage=numeric
put ANGLE "30.2"
add node AREA/usage=numeric
put AREA "0.0012005"
add node POL/usage=numeric
put POL "1"
add node SIG/usage=signal
put SIG "POL * \ISTTOKMARTE::TOP.HARDWARE.ATCA_2.IOP_9.CHANNEL_7.INP_INTEG"
set def \ISTTOKMARTE::TOP.DIAGNOSTICS.MAGNETICS.MIRNOV.PROBE9
add node ANGLE/usage=numeric
put ANGLE "30.2"
add node AREA/usage=numeric
put AREA "0.0012005"
add node POL/usage=numeric
put POL "1"
add node SIG/usage=signal
put SIG "POL * \ISTTOKMARTE::TOP.HARDWARE.ATCA_2.IOP_9.CHANNEL_8.INP_INTEG"
set def \ISTTOKMARTE::TOP.DIAGNOSTICS.MAGNETICS.MIRNOV.PROBE10
add node ANGLE/usage=numeric
put ANGLE "30.2"
add node AREA/usage=numeric
put AREA "0.0012005"
add node POL/usage=numeric
put POL "1"
add node SIG/usage=signal
put SIG "POL * \ISTTOKMARTE::TOP.HARDWARE.ATCA_2.IOP_9.CHANNEL_9.INP_INTEG"
set def \ISTTOKMARTE::TOP.DIAGNOSTICS.MAGNETICS.MIRNOV.PROBE11
add node ANGLE/usage=numeric
put ANGLE "30.2"
add node AREA/usage=numeric
put AREA "0.0012005"
add node POL/usage=numeric
put POL "-1"
add node SIG/usage=signal
put SIG "POL * \ISTTOKMARTE::TOP.HARDWARE.ATCA_2.IOP_9.CHANNEL_10.INP_INTEG"
set def \ISTTOKMARTE::TOP.DIAGNOSTICS.MAGNETICS.MIRNOV.PROBE12
add node ANGLE/usage=numeric
put ANGLE "30.2"
add node AREA/usage=numeric
put AREA "0.0012005"
add node POL/usage=numeric
put POL "1"
add node SIG/usage=signal
put SIG "POL * \ISTTOKMARTE::TOP.HARDWARE.ATCA_2.IOP_9.CHANNEL_11.INP_INTEG"
write
close
# set tree isttokmarte
# create pulse 100
exit
# edit isttokmarte/shot=-1
#TCL> set def \ISTTOKMARTE::TOP.HARDWARE.ATCA_2.IOP_9.CHANNEL_0
# TCL> put INP_DECIM "GAIN * ADC_DECIM"
#TCL> put INP_INTEG "GAIN * ADC_INTEG / .HARDWARE.ATCA_2.IOP_9.RT_DECIM / .HARDWARE.ATCA_2.IOP_9.CLOCK_FREQ"
# TCL> write

View File

@@ -0,0 +1,153 @@
from MDSplus import Device, Data, Range, Dimension, Window, Signal, Int16Array
NUM_CHANNELS = 16
class ATCA_IOP(Device):
"""
ATCA IPFN IOP Digitizer, 16 channel, 18 bit digitizer, Chopper, Integrator
This class inherits from the generic Device class
Class Device provides the basic methods required by MDSplus, in particular the Add metod
called when a new instance of this device has to be created in a tree in editing
it is therefore only necessary to add here the device specific methods such as init and store
It is however necessary to define the structure of the device, so that the superclass' Add method can
build the appropiate device subtree. This information is specified as a list of dictionaries
every element of the list specifies a node of the subtree associated with the device. The mandatory dictionary items
# for each node are:
# - path : the path name relative to the subtree root of the node
# - type : the type (usage) of the node, which can be either 'text', 'numeric', 'signal', 'action', 'structure'
# optional dictionary items formeach node are:
# - value : initial value forn that node
# - valueExpr : initial value when specified as an expression
# - options : a (list of) NCI options for the tree node, such as 'no_write_model', 'no_write_shot', 'compress_on_put'
# field parts will contain the list of dictionaries, and will be used by Device superclass.
#
# in the following methods, defice fields are referred by the syntax: self.<field_name>, where field_name is derived by the
# path of the corresponding tree node relative to the subtree (as specified by the corresponding path dictionary item), where #letters are lowercase and the dots and colons are replaced by underscores (except the first one).
# For example, tree node :ADDR is accessed by field self.addr and .CHANNEL_1:DATA by field self.channel_1_data
# All there firlds are TreeNode instances and therefore all TreeNode methods such as Data() or putData() can be used.
"""
parts = [
{'path': ':SLOT', 'type': 'numeric'}, {
'path': ':COMMENT', 'type': 'text'},
{'path': ':CLOCK_FREQ', 'type': 'numeric', 'value': 10000},
{'path': ':RT_DECIM', 'type': 'numeric', 'value': 200},
{'path': ':TRIG_SOURCE', 'type': 'numeric', 'value': 0},
{'path': ':ADC_BITS', 'type': 'numeric', 'value': 18},
]
for i in range(NUM_CHANNELS):
parts.extend([
{'path': '.CHANNEL_%d' % (i), 'type': 'structure'},
# %.5e" % (10./2**17)
{'path': '.CHANNEL_%d:GAIN' % (
i), 'type': 'numeric', 'value': 1.73887463e-05},
{'path': '.CHANNEL_%d:EO_OFFSET' % (
i), 'type': 'numeric', 'value': 0},
{'path': '.CHANNEL_%d:WO_OFFSET' % (
i), 'type': 'numeric', 'value': 0.0},
{'path': '.CHANNEL_%d:START_IDX' % (
i), 'type': 'numeric', 'value': 0},
{'path': '.CHANNEL_%d:END_IDX' % (
i), 'type': 'numeric', 'value': 1000},
{'path': '.CHANNEL_%d:ADC_DECIM' % (i), 'type': 'signal'},
{'path': '.CHANNEL_%d:ADC_DECIM_D' % (i), 'type': 'signal'},
{'path': '.CHANNEL_%d:INP_DECIM' % (i), 'type': 'signal'},
# 'value': "GAIN * ADC_DECIM"},
{'path': '.CHANNEL_%d:ADC_INTEG' % (i), 'type': 'signal'},
{'path': '.CHANNEL_%d:ADC_INTEG_D' % (i), 'type': 'signal'},
{'path': '.CHANNEL_%d:INP_INTEG' % (i), 'type': 'signal'},
# 'value': "GAIN * ADC_INTEG / RT_DECIM / CLOCK_FREQ"},
])
parts.extend([
{'path': ':INIT_ACTION', 'type': 'action',
'valueExpr': "Action(Dispatch('ATCA_SERVER','INIT',50,None),Method(None,'init',head))",
'options': ('no_write_shot',)},
{'path': ':STORE_ACTION', 'type': 'action',
'valueExpr': "Action(Dispatch('ATCA_SERVER','STORE',50,None),Method(None,'store',head))",
'options': ('no_write_shot',)},
])
del( i)
# {'path': '.CHANNEL_%d:ADC_INTEG' % (i), 'type': 'signal', 'options': (
# 'no_write_model', 'compress_on_put')},
# ----------------INIT-------------------
# init method, called to configure the ADC device. It will read configuration from the corresponding subtree
# and it will download configuration to the device
def init(self):
# Need to import some classes from MDSplus package
# The device will be configured via a shared library (libDemoAdc in the MDSplus distribution) defining the following routines:
# initialize(char *addr, int clockFreq, int postTriggerSamples)
# where clockFreq can have the following values:
# - 1 -> clock freq. = 1KHz
# - 2 -> clock freq. = 5KHz
# - 3 -> clock freq. = 10KHz
# - 4 -> clock freq. = 50 KHz
# - 5 -> clock freq. = 100KHz
# trigger(char *addr)
# acquire(char *addr, short *c1, short *c2 short *c3, short *c4)
# the routine acquire returns 4 simulated sinusoidal waveform signals at the following frequencies:
# Channel 1: 10Hz
# Channel 2: 50 Hz
# Channel 3: 100 Hz
# Channel 4: 200Hz
#
# The addr argument passed to all device routines is not used and simulates the device identifier
# used in real devices
#
# return success
return 1
# -------------STORE################################################
# store method, called to get samples from the ADC and to store waveforms in the tree
def store(self):
# import required symbols from MDSSplus and ctypes packages
# return success (odd numbers in MDSplus)
return 1
"""
# in the following, we'll get data items in two steps (on the same line):
# 1) instantiate a TreeNode object, passing the integer nid to the constructor
# 2) read and evaluate (in the case the content is an expression) its content via TreeNode.data() method
# all data access operation will be but in a try block in order to check for missing or wrong configuration data
try:
address = self.addr.data()
# we expect to get a string in addr
except:
print ('Missing addr in device')
return 0
# read the clock frequency and convert to clock mode. We use a dictionary for the conversion, and assume
clockDict = {1000: 1, 5000: 2, 10000: 3, 50000: 4, 100000: 5}
try:
clockFreq = self.clock_freq.data()
clockMode = clockDict[clockFreq]
except:
print ('Missing or invalid clock frequency')
return 0
# read Post Trigger Samples and check for consistency
try:
pts = self.pts.data()
except:
print ('Missing or invalid Post Trigger Samples')
return 0
# all required configuation collected. Call external routine initialize passing the right parameters
# we use ctypes functions to convert python variable to appropriate C types to be passed to the external routine
# try:
print(address)
deviceLibCDLL.initialize(
c_char_p(address.encode()), c_int(clockMode), c_int(pts))
#try:
# deviceLibCDLL.initialize(
# c_char_p(address), c_int(clockMode), c_int(pts))
#except:
# print('Error initializing driver')
# return 0
"""